From 51c16867d58941c0ccedffd9201b80eeb789df31 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 3 Dec 2018 17:50:39 +0900 Subject: [PATCH 001/220] Remove type conversion from LoungeTab to RoomAvailability --- osu.Game.Tests/Visual/TestCaseMultiScreen.cs | 10 ++++++++++ .../Multi/Screens/Lounge/FilterControl.cs | 19 +++++++++++++++++-- .../Screens/Multi/Screens/Lounge/Lounge.cs | 3 +-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs index 6c22fb020f..9df057806e 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs @@ -1,14 +1,24 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using NUnit.Framework; using osu.Game.Screens.Multi; +using osu.Game.Screens.Multi.Screens.Lounge; namespace osu.Game.Tests.Visual { [TestFixture] public class TestCaseMultiScreen : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(Multiplayer), + typeof(Lounge), + typeof(FilterControl) + }; + public TestCaseMultiScreen() { Multiplayer multi = new Multiplayer(); diff --git a/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs b/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs index 69cb6ad349..716a33c46b 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs @@ -17,11 +17,26 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { DisplayStyleControl.Hide(); } + + public RoomAvailability Availability + { + get + { + switch (Tabs.Current.Value) + { + default: + case LoungeTab.Public: + return RoomAvailability.Public; + case LoungeTab.Private: + return RoomAvailability.FriendsOnly; + } + } + } } public enum LoungeTab { - Public = RoomAvailability.Public, - Private = RoomAvailability.FriendsOnly, + Public, + Private, } } diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index 0af941a668..35f9743761 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -147,8 +147,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge foreach (DrawableRoom r in RoomsContainer.Children) { - r.MatchingFilter = r.MatchingFilter && - r.Room.Availability.Value == (RoomAvailability)Filter.Tabs.Current.Value; + r.MatchingFilter = r.MatchingFilter && r.Room.Availability.Value == Filter.Availability; } } From 20b843e63c86dc8d84217c29ba5a5654c576adae Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 3 Dec 2018 17:50:56 +0900 Subject: [PATCH 002/220] Add create tab --- osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs b/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs index 716a33c46b..301e235b79 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs @@ -36,6 +36,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge public enum LoungeTab { + Create, Public, Private, } From 53a54f86341d89250154bedb95636cad6fc21042 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 3 Dec 2018 17:54:10 +0900 Subject: [PATCH 003/220] Renamespace room settings --- osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 2 +- .../{Screens/Match/Settings => Components}/GameTypePicker.cs | 3 +-- .../Match/Settings => Components}/RoomAvailabilityPicker.cs | 2 +- .../Match/Settings => Components}/RoomSettingsOverlay.cs | 2 +- osu.Game/Screens/Multi/Screens/Match/Match.cs | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) rename osu.Game/Screens/Multi/{Screens/Match/Settings => Components}/GameTypePicker.cs (97%) rename osu.Game/Screens/Multi/{Screens/Match/Settings => Components}/RoomAvailabilityPicker.cs (98%) rename osu.Game/Screens/Multi/{Screens/Match/Settings => Components}/RoomSettingsOverlay.cs (99%) diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index 40742ce709..55e3df679d 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -5,7 +5,7 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Testing.Input; using osu.Game.Online.Multiplayer; -using osu.Game.Screens.Multi.Screens.Match.Settings; +using osu.Game.Screens.Multi.Components; using osuTK.Input; namespace osu.Game.Tests.Visual diff --git a/osu.Game/Screens/Multi/Screens/Match/Settings/GameTypePicker.cs b/osu.Game/Screens/Multi/Components/GameTypePicker.cs similarity index 97% rename from osu.Game/Screens/Multi/Screens/Match/Settings/GameTypePicker.cs rename to osu.Game/Screens/Multi/Components/GameTypePicker.cs index cd8b081b4e..9058185e28 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Settings/GameTypePicker.cs +++ b/osu.Game/Screens/Multi/Components/GameTypePicker.cs @@ -9,10 +9,9 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Online.Multiplayer; -using osu.Game.Screens.Multi.Components; using osuTK; -namespace osu.Game.Screens.Multi.Screens.Match.Settings +namespace osu.Game.Screens.Multi.Components { public class GameTypePicker : TabControl { diff --git a/osu.Game/Screens/Multi/Screens/Match/Settings/RoomAvailabilityPicker.cs b/osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs similarity index 98% rename from osu.Game/Screens/Multi/Screens/Match/Settings/RoomAvailabilityPicker.cs rename to osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs index 251bd062ec..f0a2a2e8dc 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Settings/RoomAvailabilityPicker.cs +++ b/osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs @@ -13,7 +13,7 @@ using osu.Game.Online.Multiplayer; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Screens.Match.Settings +namespace osu.Game.Screens.Multi.Components { public class RoomAvailabilityPicker : TabControl { diff --git a/osu.Game/Screens/Multi/Screens/Match/Settings/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs similarity index 99% rename from osu.Game/Screens/Multi/Screens/Match/Settings/RoomSettingsOverlay.cs rename to osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs index d45ba48f0e..df70e577d5 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Settings/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.SearchableList; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Screens.Match.Settings +namespace osu.Game.Screens.Multi.Components { public class RoomSettingsOverlay : FocusedOverlayContainer { diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs index f7d98df60e..5bfc1f59bd 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; -using osu.Game.Screens.Multi.Screens.Match.Settings; +using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Select; using osu.Game.Users; From 6a28e8c696823e3d1575efa6b8a6500837c96289 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 3 Dec 2018 18:30:26 +0900 Subject: [PATCH 004/220] Add settings to lounge --- osu.Game/Online/Multiplayer/Room.cs | 6 +++--- .../Screens/Multi/Screens/Lounge/Lounge.cs | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index b076afbcdb..cb2979d733 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -10,11 +10,11 @@ namespace osu.Game.Online.Multiplayer { public class Room { - public Bindable Name = new Bindable(); + public Bindable Name = new Bindable("My awesome room!"); public Bindable Host = new Bindable(); - public Bindable Status = new Bindable(); + public Bindable Status = new Bindable(new RoomStatusOpen()); public Bindable Availability = new Bindable(); - public Bindable Type = new Bindable(); + public Bindable Type = new Bindable(new GameTypeVersus()); public Bindable Beatmap = new Bindable(); public Bindable MaxParticipants = new Bindable(); public Bindable> Participants = new Bindable>(); diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index 35f9743761..eb16524776 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -20,6 +20,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { private readonly Container content; private readonly SearchContainer search; + private readonly RoomSettingsOverlay settings; protected readonly FilterControl Filter; protected readonly FillFlowContainer RoomsContainer; @@ -56,7 +57,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { Children = new Drawable[] { - Filter = new FilterControl(), + Filter = new FilterControl { Depth = -1 }, content = new Container { RelativeSizeAxes = Axes.Both, @@ -91,8 +92,17 @@ namespace osu.Game.Screens.Multi.Screens.Lounge RelativeSizeAxes = Axes.Both, Width = 0.45f, }, + new Container + { + RelativeSizeAxes = Axes.Both, + Child = settings = new RoomSettingsOverlay(new Room()) + { + RelativeSizeAxes = Axes.Both, + Height = 0.9f, + }, + }, }, - }, + } }; Filter.Search.Current.ValueChanged += s => filterRooms(); @@ -143,6 +153,11 @@ namespace osu.Game.Screens.Multi.Screens.Lounge private void filterRooms() { + if (Filter.Tabs.Current.Value == LoungeTab.Create) + settings.Show(); + else + settings.Hide(); + search.SearchTerm = Filter.Search.Current.Value ?? string.Empty; foreach (DrawableRoom r in RoomsContainer.Children) From c6c255718b9a9d65e96f91d8e4e09fb3891f2188 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Mon, 3 Dec 2018 22:37:26 +0300 Subject: [PATCH 005/220] Handle ModAutoplay during score construction in the Player --- osu.Game.Tests/Visual/TestCaseReplay.cs | 2 +- osu.Game/Rulesets/Mods/ModAutoplay.cs | 2 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 15 ++++++++------- osu.Game/Screens/Play/Player.cs | 4 ++-- osu.Game/Screens/Play/ReplayPlayer.cs | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs index e0ea613534..2f217d013b 100644 --- a/osu.Game.Tests/Visual/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/TestCaseReplay.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual // Reset the mods Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay)); - return new ReplayPlayer(new Score { Replay = dummyRulesetContainer.Replay }); + return new ReplayPlayer(new Score { Replay = dummyRulesetContainer.ReplayScore.Replay }); } } } diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index 932439618d..72ae88d67a 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mods public override bool HasImplementation => GetType().GenericTypeArguments.Length == 0; - public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) => rulesetContainer.SetReplay(CreateReplayScore(rulesetContainer.Beatmap)?.Replay); + public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) => rulesetContainer.SetReplayScore(CreateReplayScore(rulesetContainer.Beatmap)); } public abstract class ModAutoplay : Mod, IApplicableFailOverride diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 5967cad8d1..3dbaf0ce00 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -22,6 +22,7 @@ using osu.Game.Overlays; using osu.Game.Replays; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; namespace osu.Game.Rulesets.UI { @@ -125,7 +126,7 @@ namespace osu.Game.Rulesets.UI protected virtual ReplayInputHandler CreateReplayInputHandler(Replay replay) => null; - public Replay Replay { get; private set; } + public Score ReplayScore { get; private set; } /// /// Whether the game is paused. Used to block user input. @@ -135,14 +136,14 @@ namespace osu.Game.Rulesets.UI /// /// Sets a replay to be used, overriding local input. /// - /// The replay, null for local input. - public virtual void SetReplay(Replay replay) + /// The replay, null for local input. + public virtual void SetReplayScore(Score replayScore) { if (ReplayInputManager == null) throw new InvalidOperationException($"A {nameof(KeyBindingInputManager)} which supports replay loading is not available"); - Replay = replay; - ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null; + ReplayScore = replayScore; + ReplayInputManager.ReplayInputHandler = replayScore != null ? CreateReplayInputHandler(replayScore.Replay) : null; HasReplayLoaded.Value = ReplayInputManager.ReplayInputHandler != null; } @@ -291,9 +292,9 @@ namespace osu.Game.Rulesets.UI mod.ReadFromConfig(config); } - public override void SetReplay(Replay replay) + public override void SetReplayScore(Score replayScore) { - base.SetReplay(replay); + base.SetReplayScore(replayScore); if (ReplayInputManager?.ReplayInputHandler != null) ReplayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index bf44e9e636..7e80bd92c9 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -277,7 +277,7 @@ namespace osu.Game.Screens.Play if (!IsCurrentScreen) return; var score = CreateScore(); - if (RulesetContainer.Replay == null) + if (RulesetContainer.ReplayScore == null) scoreManager.Import(score, true); Push(new Results(score)); @@ -289,7 +289,7 @@ namespace osu.Game.Screens.Play protected virtual ScoreInfo CreateScore() { - var score = new ScoreInfo + var score = RulesetContainer?.ReplayScore?.ScoreInfo ?? new ScoreInfo { Beatmap = Beatmap.Value.BeatmapInfo, Ruleset = ruleset, diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index fe77fd57f2..04cf922d74 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Play protected override void LoadComplete() { base.LoadComplete(); - RulesetContainer.SetReplay(score.Replay); + RulesetContainer.SetReplayScore(score); } protected override ScoreInfo CreateScore() => score.ScoreInfo; From e22cefc27d8139841f9adee55959493f21423b30 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 3 Dec 2018 20:50:40 +0900 Subject: [PATCH 006/220] Immediately select newly-created rooms --- osu.Game/Online/Multiplayer/Room.cs | 3 +- .../Screens/Multi/Components/DrawableRoom.cs | 20 +------ .../Multi/Components/RoomSettingsOverlay.cs | 15 ++++- .../Screens/Multi/Screens/Lounge/Lounge.cs | 59 +++++++++++-------- osu.Game/Screens/Multi/Screens/Match/Match.cs | 2 + .../Multi/Screens/Match/Participants.cs | 3 +- 6 files changed, 58 insertions(+), 44 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index cb2979d733..f4885b6a4a 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using osu.Framework.Configuration; using osu.Game.Beatmaps; using osu.Game.Users; @@ -17,6 +18,6 @@ namespace osu.Game.Online.Multiplayer public Bindable Type = new Bindable(new GameTypeVersus()); public Bindable Beatmap = new Bindable(); public Bindable MaxParticipants = new Bindable(); - public Bindable> Participants = new Bindable>(); + public Bindable> Participants = new Bindable>(Enumerable.Empty()); } } diff --git a/osu.Game/Screens/Multi/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Components/DrawableRoom.cs index 05ec2f0fac..c5fac7170f 100644 --- a/osu.Game/Screens/Multi/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Components/DrawableRoom.cs @@ -34,6 +34,8 @@ namespace osu.Game.Screens.Multi.Components private const float side_strip_width = 5; private const float cover_width = 145; + public Action SelectionRequested; + private readonly Box selectionBox; private readonly Bindable nameBind = new Bindable(); @@ -76,17 +78,6 @@ namespace osu.Game.Screens.Multi.Components } } - private Action action; - public new Action Action - { - get { return action; } - set - { - action = value; - Enabled.Value = action != null; - } - } - public event Action StateChanged; public DrawableRoom(Room room) @@ -248,12 +239,7 @@ namespace osu.Game.Screens.Multi.Components protected override bool OnClick(ClickEvent e) { - if (Enabled.Value) - { - Action?.Invoke(this); - State = SelectionState.Selected; - } - + State = SelectionState.Selected; return true; } } diff --git a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs index df70e577d5..b3d7937433 100644 --- a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -21,6 +22,16 @@ namespace osu.Game.Screens.Multi.Components private const float transition_duration = 350; private const float field_padding = 45; + /// + /// Invoked when room settings were applied. + /// + public Action Applied; + + /// + /// The room which settings are being applied to. + /// + public readonly Room Room; + private readonly Bindable nameBind = new Bindable(); private readonly Bindable availabilityBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); @@ -36,6 +47,8 @@ namespace osu.Game.Screens.Multi.Components public RoomSettingsOverlay(Room room) { + Room = room; + Masking = true; Child = content = new Container @@ -185,7 +198,7 @@ namespace osu.Game.Screens.Multi.Components else maxParticipantsBind.Value = null; - Hide(); + Applied?.Invoke(); } private class SettingsTextBox : OsuTextBox diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index eb16524776..96728c01f9 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -30,29 +29,6 @@ namespace osu.Game.Screens.Multi.Screens.Lounge protected override Container TransitionContent => content; - private IEnumerable rooms; - public IEnumerable Rooms - { - get { return rooms; } - set - { - if (Equals(value, rooms)) return; - rooms = value; - - var enumerable = rooms.ToList(); - - RoomsContainer.Children = enumerable.Select(r => new DrawableRoom(r) - { - Action = didSelect, - }).ToList(); - - if (!enumerable.Contains(Inspector.Room)) - Inspector.Room = null; - - filterRooms(); - } - } - public Lounge() { Children = new Drawable[] @@ -108,6 +84,12 @@ namespace osu.Game.Screens.Multi.Screens.Lounge Filter.Search.Current.ValueChanged += s => filterRooms(); Filter.Tabs.Current.ValueChanged += t => filterRooms(); Filter.Search.Exit += Exit; + + settings.Applied = () => + { + var drawableRoom = addRoom(settings.Room); + drawableRoom.State = SelectionState.Selected; + }; } protected override void UpdateAfterChildren() @@ -122,6 +104,35 @@ namespace osu.Game.Screens.Multi.Screens.Lounge }; } + public IEnumerable Rooms + { + set + { + RoomsContainer.ForEach(r => r.Action = null); + RoomsContainer.Clear(); + + foreach (var room in value) + addRoom(room); + } + } + + private DrawableRoom addRoom(Room room) + { + var drawableRoom = new DrawableRoom(room); + + drawableRoom.StateChanged += s => + { + if (s == SelectionState.Selected) + didSelect(drawableRoom); + }; + + RoomsContainer.Add(drawableRoom); + + filterRooms(); + + return drawableRoom; + } + protected override void OnFocus(FocusEvent e) { GetContainingInputManager().ChangeFocus(Filter.Search); diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs index 5bfc1f59bd..339db2e158 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -88,6 +88,8 @@ namespace osu.Game.Screens.Multi.Screens.Match header.Tabs.Current.Value = MatchHeaderPage.Room; }; + settings.Applied = () => settings.Hide(); + nameBind.BindTo(room.Name); nameBind.BindValueChanged(n => info.Name = n, true); diff --git a/osu.Game/Screens/Multi/Screens/Match/Participants.cs b/osu.Game/Screens/Multi/Screens/Match/Participants.cs index 55541a1acd..a5ac93fffc 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Participants.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Participants.cs @@ -19,7 +19,8 @@ namespace osu.Game.Screens.Multi.Screens.Match public IEnumerable Users { - set { + set + { usersFlow.Children = value.Select(u => new UserPanel(u) { Anchor = Anchor.TopCentre, From d8739d9dee1f0cb3e42608c0a98d7459e9958c45 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Dec 2018 15:25:41 +0900 Subject: [PATCH 007/220] Fix creating a new room re-using the existing model --- osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 2 +- .../Multi/Components/RoomSettingsOverlay.cs | 44 ++++++++++++++----- .../Screens/Multi/Screens/Lounge/Lounge.cs | 6 ++- osu.Game/Screens/Multi/Screens/Match/Match.cs | 3 +- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index 55e3df679d..83e589b260 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -105,7 +105,7 @@ namespace osu.Game.Tests.Visual set => TypePicker.Current.Value = value; } - public TestRoomSettingsOverlay(Room room) : base(room) + public TestRoomSettingsOverlay(Room room) : base() { } diff --git a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs index b3d7937433..896017b219 100644 --- a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs @@ -27,11 +27,6 @@ namespace osu.Game.Screens.Multi.Components /// public Action Applied; - /// - /// The room which settings are being applied to. - /// - public readonly Room Room; - private readonly Bindable nameBind = new Bindable(); private readonly Bindable availabilityBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); @@ -45,10 +40,8 @@ namespace osu.Game.Screens.Multi.Components protected readonly GameTypePicker TypePicker; protected readonly TriangleButton ApplyButton; - public RoomSettingsOverlay(Room room) + public RoomSettingsOverlay() { - Room = room; - Masking = true; Child = content = new Container @@ -156,10 +149,7 @@ namespace osu.Game.Screens.Multi.Components typeBind.ValueChanged += t => TypePicker.Current.Value = t; maxParticipantsBind.ValueChanged += m => MaxParticipantsField.Text = m?.ToString(); - nameBind.BindTo(room.Name); - availabilityBind.BindTo(room.Availability); - typeBind.BindTo(room.Type); - maxParticipantsBind.BindTo(room.MaxParticipants); + Room = new Room(); } [BackgroundDependencyLoader] @@ -168,6 +158,36 @@ namespace osu.Game.Screens.Multi.Components typeLabel.Colour = colours.Yellow; } + private Room room; + + /// + /// The room which settings are being applied to. + /// + public Room Room + { + get => room; + set + { + if (room == value) + return; + + room = value; + + nameBind.UnbindBindings(); + availabilityBind.UnbindBindings(); + typeBind.UnbindBindings(); + maxParticipantsBind.UnbindBindings(); + + if (room != null) + { + nameBind.BindTo(room.Name); + availabilityBind.BindTo(room.Availability); + typeBind.BindTo(room.Type); + maxParticipantsBind.BindTo(room.MaxParticipants); + } + } + } + protected override void PopIn() { // reapply the rooms values if the overlay was completely closed diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index 96728c01f9..475490e399 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -71,10 +71,11 @@ namespace osu.Game.Screens.Multi.Screens.Lounge new Container { RelativeSizeAxes = Axes.Both, - Child = settings = new RoomSettingsOverlay(new Room()) + Child = settings = new RoomSettingsOverlay { RelativeSizeAxes = Axes.Both, Height = 0.9f, + Room = new Room() }, }, }, @@ -153,6 +154,9 @@ namespace osu.Game.Screens.Multi.Screens.Lounge protected override void OnResuming(Screen last) { base.OnResuming(last); + + settings.Room = new Room(); + Filter.Search.HoldFocus = true; } diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs index 339db2e158..f0f7a1dd6b 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -57,10 +57,11 @@ namespace osu.Game.Screens.Multi.Screens.Match { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Header.HEIGHT }, - Child = settings = new RoomSettingsOverlay(room) + Child = settings = new RoomSettingsOverlay { RelativeSizeAxes = Axes.Both, Height = 0.9f, + Room = room }, }, }; From a02e025f06a1e17971daabbce53c3cf95b8efb4c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Dec 2018 15:26:06 +0900 Subject: [PATCH 008/220] Fix selections not working anymore --- .../Screens/Multi/Components/DrawableRoom.cs | 6 +-- .../Screens/Multi/Screens/Lounge/Lounge.cs | 49 ++++++++++++------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Components/DrawableRoom.cs index c5fac7170f..2f26f53e8b 100644 --- a/osu.Game/Screens/Multi/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Components/DrawableRoom.cs @@ -34,6 +34,8 @@ namespace osu.Game.Screens.Multi.Components private const float side_strip_width = 5; private const float cover_width = 145; + public event Action StateChanged; + public Action SelectionRequested; private readonly Box selectionBox; @@ -78,8 +80,6 @@ namespace osu.Game.Screens.Multi.Components } } - public event Action StateChanged; - public DrawableRoom(Room room) { Room = room; @@ -239,7 +239,7 @@ namespace osu.Game.Screens.Multi.Components protected override bool OnClick(ClickEvent e) { - State = SelectionState.Selected; + SelectionRequested?.Invoke(); return true; } } diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index 475490e399..e820b23e56 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osu.Framework.Screens; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; @@ -86,11 +87,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge Filter.Tabs.Current.ValueChanged += t => filterRooms(); Filter.Search.Exit += Exit; - settings.Applied = () => - { - var drawableRoom = addRoom(settings.Room); - drawableRoom.State = SelectionState.Selected; - }; + settings.Applied = () => createRoom(settings.Room); } protected override void UpdateAfterChildren() @@ -121,11 +118,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { var drawableRoom = new DrawableRoom(room); - drawableRoom.StateChanged += s => - { - if (s == SelectionState.Selected) - didSelect(drawableRoom); - }; + drawableRoom.SelectionRequested = () => selectionRequested(drawableRoom); RoomsContainer.Add(drawableRoom); @@ -163,6 +156,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge protected override void OnSuspending(Screen next) { base.OnSuspending(next); + Filter.Search.HoldFocus = false; } @@ -181,19 +175,38 @@ namespace osu.Game.Screens.Multi.Screens.Lounge } } - private void didSelect(DrawableRoom room) + private void selectionRequested(DrawableRoom room) { - RoomsContainer.Children.ForEach(c => + if (room.State == SelectionState.Selected) + openRoom(room); + else { - if (c != room) - c.State = SelectionState.NotSelected; - }); + RoomsContainer.ForEach(c => c.State = c == room ? SelectionState.Selected : SelectionState.NotSelected); + Inspector.Room = room.Room; + } + } + private void openRoom(DrawableRoom room) + { + if (!IsCurrentScreen) + return; + + RoomsContainer.ForEach(c => c.State = c == room ? SelectionState.Selected : SelectionState.NotSelected); Inspector.Room = room.Room; - // open the room if its selected and is clicked again - if (room.State == SelectionState.Selected) - Push(new Match.Match(room.Room)); + Push(new Match.Match(room.Room)); + } + + private void createRoom(Room room) + { + openRoom(addRoom(room)); + + this.Delay(WaveContainer.APPEAR_DURATION).Schedule(() => + { + Filter.Tabs.Current.Value = LoungeTab.Public; + settings.Hide(); + settings.FinishTransforms(true); + }); } private class RoomsFilterContainer : FillFlowContainer, IHasFilterableChildren From 6e5716c3f3ba5d6e782cf1d535a9a9666238c702 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Dec 2018 15:31:48 +0900 Subject: [PATCH 009/220] Adjust transition --- osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 4 ---- osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs | 10 +--------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index 83e589b260..f4dce329c1 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -105,10 +105,6 @@ namespace osu.Game.Tests.Visual set => TypePicker.Current.Value = value; } - public TestRoomSettingsOverlay(Room room) : base() - { - } - public void ClickApplyButton(ManualInputManager inputManager) { inputManager.MoveMouseTo(ApplyButton); diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index e820b23e56..30da448dde 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osu.Framework.Screens; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; @@ -156,7 +155,6 @@ namespace osu.Game.Screens.Multi.Screens.Lounge protected override void OnSuspending(Screen next) { base.OnSuspending(next); - Filter.Search.HoldFocus = false; } @@ -200,13 +198,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge private void createRoom(Room room) { openRoom(addRoom(room)); - - this.Delay(WaveContainer.APPEAR_DURATION).Schedule(() => - { - Filter.Tabs.Current.Value = LoungeTab.Public; - settings.Hide(); - settings.FinishTransforms(true); - }); + Filter.Tabs.Current.Value = LoungeTab.Public; } private class RoomsFilterContainer : FillFlowContainer, IHasFilterableChildren From f2a57ce270363407d088b3096ab9bd7662f56667 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Dec 2018 17:23:58 +0900 Subject: [PATCH 010/220] Fix room host not being set --- osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 2 +- .../Multi/Components/CreateRoomOverlay.cs | 20 +++++++++++++++++++ .../Screens/Multi/Screens/Lounge/Lounge.cs | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index f4dce329c1..e62afec6b4 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual MaxParticipants = { Value = 10 }, }; - Add(overlay = new TestRoomSettingsOverlay(room) + Add(overlay = new TestRoomSettingsOverlay { RelativeSizeAxes = Axes.Both, Height = 0.75f, diff --git a/osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs b/osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs new file mode 100644 index 0000000000..7e08e980a3 --- /dev/null +++ b/osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Online.API; + +namespace osu.Game.Screens.Multi.Components +{ + public class CreateRoomOverlay : RoomSettingsOverlay + { + [Resolved] + private APIAccess api { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + Room.Host.Value = api.LocalUser; + } + } +} diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index 30da448dde..26d25aabfc 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -71,7 +71,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge new Container { RelativeSizeAxes = Axes.Both, - Child = settings = new RoomSettingsOverlay + Child = settings = new CreateRoomOverlay { RelativeSizeAxes = Axes.Both, Height = 0.9f, From b251129c596a62841f34c9830f75e8c5e2f6a397 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Dec 2018 17:43:27 +0900 Subject: [PATCH 011/220] Block going into multiplayer while logged out --- osu.Game/Screens/Menu/ButtonSystem.cs | 33 +++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index ae1f27610b..943dfa53af 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -17,7 +17,9 @@ using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Input; using osu.Game.Input.Bindings; +using osu.Game.Online.API; using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; using osuTK; using osuTK.Graphics; using osuTK.Input; @@ -90,7 +92,7 @@ namespace osu.Game.Screens.Menu buttonArea.Flow.CentreTarget = iconFacade; buttonsPlay.Add(new Button(@"solo", @"button-solo-select", FontAwesome.fa_user, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P)); - buttonsPlay.Add(new Button(@"multi", @"button-generic-select", FontAwesome.fa_users, new Color4(94, 63, 186, 255), () => OnMulti?.Invoke(), 0, Key.M)); + buttonsPlay.Add(new Button(@"multi", @"button-generic-select", FontAwesome.fa_users, new Color4(94, 63, 186, 255), onMulti, 0, Key.M)); buttonsPlay.Add(new Button(@"chart", @"button-generic-select", FontAwesome.fa_osu_charts, new Color4(80, 53, 160, 255), () => OnChart?.Invoke())); buttonsPlay.ForEach(b => b.VisibleState = ButtonSystemState.Play); @@ -103,19 +105,40 @@ namespace osu.Game.Screens.Menu buttonArea.AddRange(buttonsTopLevel); } - private OsuGame game; + [Resolved] + private OsuGame game { get; set; } + + [Resolved] + private APIAccess api { get; set; } + + [Resolved] + private NotificationOverlay notifications { get; set; } [BackgroundDependencyLoader(true)] - private void load(AudioManager audio, OsuGame game, IdleTracker idleTracker) + private void load(AudioManager audio, IdleTracker idleTracker) { - this.game = game; - isIdle.ValueChanged += updateIdleState; + if (idleTracker != null) isIdle.BindTo(idleTracker.IsIdle); sampleBack = audio.Sample.Get(@"Menu/button-back-select"); } + private void onMulti() + { + if (!api.IsLoggedIn) + { + notifications.Post(new SimpleNotification + { + Text = "You gotta be logged in to multi 'yo!", + Icon = FontAwesome.fa_globe + }); + + return; + } + OnMulti?.Invoke(); + } + private void updateIdleState(bool isIdle) { if (isIdle && State != ButtonSystemState.Exit) From a7ac544e12c245038ee7afe0d39fef604a5f1ad5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Dec 2018 17:43:44 +0900 Subject: [PATCH 012/220] Add interface for the multiplayer screen short title --- osu.Game/Screens/Multi/Header.cs | 2 +- osu.Game/Screens/Multi/Screens/IMultiplayerScreen.cs | 10 ++++++++++ osu.Game/Screens/Multi/Screens/Match/Match.cs | 3 ++- osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs | 7 ++----- osu.Game/Screens/Select/MatchSongSelect.cs | 6 +++++- 5 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 osu.Game/Screens/Multi/Screens/IMultiplayerScreen.cs diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 6bd300eadc..612a3e6993 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Multi }, }; - breadcrumbs.Current.ValueChanged += s => screenType.Text = ((MultiplayerScreen)s).Type.ToLowerInvariant(); + breadcrumbs.Current.ValueChanged += s => screenType.Text = ((IMultiplayerScreen)s).ShortTitle.ToLowerInvariant(); breadcrumbs.Current.TriggerChange(); } diff --git a/osu.Game/Screens/Multi/Screens/IMultiplayerScreen.cs b/osu.Game/Screens/Multi/Screens/IMultiplayerScreen.cs new file mode 100644 index 0000000000..0b6ebc3716 --- /dev/null +++ b/osu.Game/Screens/Multi/Screens/IMultiplayerScreen.cs @@ -0,0 +1,10 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Screens.Multi.Screens +{ + public interface IMultiplayerScreen + { + string ShortTitle { get; } + } +} diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs index f0f7a1dd6b..2dbe0a9c3a 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -28,9 +28,10 @@ namespace osu.Game.Screens.Multi.Screens.Match protected override Container TransitionContent => participants; - public override string Type => "room"; public override string Title => room.Name.Value; + public override string ShortTitle => "room"; + public Match(Room room) { this.room = room; diff --git a/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs b/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs index 00c2613d54..fd866a5fef 100644 --- a/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs +++ b/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs @@ -8,14 +8,11 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Multi.Screens { - public abstract class MultiplayerScreen : OsuScreen + public abstract class MultiplayerScreen : OsuScreen, IMultiplayerScreen { protected virtual Container TransitionContent => Content; - /// - /// The type to display in the title of the . - /// - public virtual string Type => Title; + public virtual string ShortTitle => Title; protected override void OnEntering(Screen last) { diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 339392d5cf..28525215fb 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -1,10 +1,14 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Screens.Multi.Screens; + namespace osu.Game.Screens.Select { - public class MatchSongSelect : SongSelect + public class MatchSongSelect : SongSelect, IMultiplayerScreen { + public string ShortTitle => "song selection"; + protected override bool OnStart() { if (IsCurrentScreen) Exit(); From c469d12d63be181e6d89c565419b1b4122030167 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Dec 2018 18:18:17 +0900 Subject: [PATCH 013/220] Set room host when the room is refreshed --- .../Screens/Multi/Components/CreateRoomOverlay.cs | 13 +++++++++++++ .../Screens/Multi/Components/RoomSettingsOverlay.cs | 2 +- osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs | 12 ++++++------ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs b/osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs index 7e08e980a3..3a6224da26 100644 --- a/osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs +++ b/osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Game.Online.API; +using osu.Game.Online.Multiplayer; namespace osu.Game.Screens.Multi.Components { @@ -16,5 +17,17 @@ namespace osu.Game.Screens.Multi.Components { Room.Host.Value = api.LocalUser; } + + public override Room Room + { + get => base.Room; + set + { + base.Room = value; + + if (api != null && value != null) + value.Host.Value = api.LocalUser; + } + } } } diff --git a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs index 896017b219..f50eefe4c6 100644 --- a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs @@ -163,7 +163,7 @@ namespace osu.Game.Screens.Multi.Components /// /// The room which settings are being applied to. /// - public Room Room + public virtual Room Room { get => room; set diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index 26d25aabfc..f307032600 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { private readonly Container content; private readonly SearchContainer search; - private readonly RoomSettingsOverlay settings; + private readonly CreateRoomOverlay createRoomOverlay; protected readonly FilterControl Filter; protected readonly FillFlowContainer RoomsContainer; @@ -71,7 +71,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge new Container { RelativeSizeAxes = Axes.Both, - Child = settings = new CreateRoomOverlay + Child = createRoomOverlay = new CreateRoomOverlay { RelativeSizeAxes = Axes.Both, Height = 0.9f, @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge Filter.Tabs.Current.ValueChanged += t => filterRooms(); Filter.Search.Exit += Exit; - settings.Applied = () => createRoom(settings.Room); + createRoomOverlay.Applied = () => createRoom(createRoomOverlay.Room); } protected override void UpdateAfterChildren() @@ -147,7 +147,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { base.OnResuming(last); - settings.Room = new Room(); + createRoomOverlay.Room = new Room(); Filter.Search.HoldFocus = true; } @@ -161,9 +161,9 @@ namespace osu.Game.Screens.Multi.Screens.Lounge private void filterRooms() { if (Filter.Tabs.Current.Value == LoungeTab.Create) - settings.Show(); + createRoomOverlay.Show(); else - settings.Hide(); + createRoomOverlay.Hide(); search.SearchTerm = Filter.Search.Current.Value ?? string.Empty; From ec837907348eeeef243d660d99d8293953411f94 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Dec 2018 18:58:45 +0900 Subject: [PATCH 014/220] Add timeshift game type --- osu.Game.Tests/Visual/TestCaseMatch.cs | 9 +++++ osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 8 +++++ osu.Game/Online/Multiplayer/GameType.cs | 33 +++++++++++++++++++ osu.Game/Online/Multiplayer/Room.cs | 2 +- .../Multi/Components/GameTypePicker.cs | 15 ++++++++- 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatch.cs b/osu.Game.Tests/Visual/TestCaseMatch.cs index bb22358425..ae19b9720e 100644 --- a/osu.Game.Tests/Visual/TestCaseMatch.cs +++ b/osu.Game.Tests/Visual/TestCaseMatch.cs @@ -1,11 +1,14 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; +using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Screens.Match; using osu.Game.Users; @@ -14,6 +17,12 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseMatch : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(TestCaseMatch), + typeof(GameTypePicker) + }; + [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index e62afec6b4..af41563e30 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Testing.Input; @@ -13,6 +15,12 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseRoomSettings : ManualInputManagerTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(RoomSettingsOverlay), + typeof(GameTypePicker) + }; + private readonly Room room; private readonly TestRoomSettingsOverlay overlay; diff --git a/osu.Game/Online/Multiplayer/GameType.cs b/osu.Game/Online/Multiplayer/GameType.cs index 8d39e8f59d..ced6d7d318 100644 --- a/osu.Game/Online/Multiplayer/GameType.cs +++ b/osu.Game/Online/Multiplayer/GameType.cs @@ -13,6 +13,9 @@ namespace osu.Game.Online.Multiplayer public abstract class GameType { public abstract string Name { get; } + + public abstract bool IsAvailable { get; } + public abstract Drawable GetIcon(OsuColour colours, float size); public override int GetHashCode() => GetType().GetHashCode(); @@ -22,6 +25,9 @@ namespace osu.Game.Online.Multiplayer public class GameTypeTag : GameType { public override string Name => "Tag"; + + public override bool IsAvailable => false; + public override Drawable GetIcon(OsuColour colours, float size) { return new SpriteIcon @@ -39,6 +45,9 @@ namespace osu.Game.Online.Multiplayer public class GameTypeVersus : GameType { public override string Name => "Versus"; + + public override bool IsAvailable => false; + public override Drawable GetIcon(OsuColour colours, float size) { return new VersusRow(colours.Blue, colours.Blue, size * 0.6f) @@ -52,6 +61,9 @@ namespace osu.Game.Online.Multiplayer public class GameTypeTagTeam : GameType { public override string Name => "Tag Team"; + + public override bool IsAvailable => false; + public override Drawable GetIcon(OsuColour colours, float size) { return new FillFlowContainer @@ -85,6 +97,9 @@ namespace osu.Game.Online.Multiplayer public class GameTypeTeamVersus : GameType { public override string Name => "Team Versus"; + + public override bool IsAvailable => false; + public override Drawable GetIcon(OsuColour colours, float size) { return new FillFlowContainer @@ -146,4 +161,22 @@ namespace osu.Game.Online.Multiplayer }; } } + + public class GameTypeTimeshift : GameType + { + public override string Name => "Timeshift"; + + public override bool IsAvailable => true; + + public override Drawable GetIcon(OsuColour colours, float size) => new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_osu_charts, + X = -2, // The icon is off-centre + Size = new Vector2(size), + Colour = colours.Blue, + Shadow = false + }; + } } diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index f4885b6a4a..8395b7e638 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -15,7 +15,7 @@ namespace osu.Game.Online.Multiplayer public Bindable Host = new Bindable(); public Bindable Status = new Bindable(new RoomStatusOpen()); public Bindable Availability = new Bindable(); - public Bindable Type = new Bindable(new GameTypeVersus()); + public Bindable Type = new Bindable(new GameTypeTimeshift()); public Bindable Beatmap = new Bindable(); public Bindable MaxParticipants = new Bindable(); public Bindable> Participants = new Bindable>(Enumerable.Empty()); diff --git a/osu.Game/Screens/Multi/Components/GameTypePicker.cs b/osu.Game/Screens/Multi/Components/GameTypePicker.cs index 9058185e28..9cd1a7dc14 100644 --- a/osu.Game/Screens/Multi/Components/GameTypePicker.cs +++ b/osu.Game/Screens/Multi/Components/GameTypePicker.cs @@ -19,6 +19,7 @@ namespace osu.Game.Screens.Multi.Components private const float selection_width = 3; protected override TabItem CreateTabItem(GameType value) => new GameTypePickerItem(value); + protected override Dropdown CreateDropdown() => null; public GameTypePicker() @@ -30,6 +31,7 @@ namespace osu.Game.Screens.Multi.Components AddItem(new GameTypeVersus()); AddItem(new GameTypeTagTeam()); AddItem(new GameTypeTeamVersus()); + AddItem(new GameTypeTimeshift()); } private class GameTypePickerItem : TabItem @@ -38,7 +40,8 @@ namespace osu.Game.Screens.Multi.Components private readonly CircularContainer hover, selection; - public GameTypePickerItem(GameType value) : base(value) + public GameTypePickerItem(GameType value) + : base(value) { AutoSizeAxes = Axes.Both; @@ -81,6 +84,9 @@ namespace osu.Game.Screens.Multi.Components private void load(OsuColour colours) { selection.Colour = colours.Yellow; + + if (!Value.IsAvailable) + Colour = colours.Gray5; } protected override bool OnHover(HoverEvent e) @@ -95,6 +101,13 @@ namespace osu.Game.Screens.Multi.Components base.OnHoverLost(e); } + protected override bool OnClick(ClickEvent e) + { + if (!Value.IsAvailable) + return true; + return base.OnClick(e); + } + protected override void OnActivated() { selection.FadeIn(transition_duration, Easing.OutQuint); From e7d7e005169abffc7039258041722c184b4eb1a4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Dec 2018 17:01:14 +0900 Subject: [PATCH 015/220] Better disabling of various controls --- osu.Game/Online/Multiplayer/GameType.cs | 12 ----- .../Multi/Components/DisableableTabControl.cs | 44 +++++++++++++++++++ .../Multi/Components/GameTypePicker.cs | 14 +----- .../Components/RoomAvailabilityPicker.cs | 6 +-- .../Multi/Components/RoomSettingsOverlay.cs | 17 +++++++ 5 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 osu.Game/Screens/Multi/Components/DisableableTabControl.cs diff --git a/osu.Game/Online/Multiplayer/GameType.cs b/osu.Game/Online/Multiplayer/GameType.cs index ced6d7d318..8c9d635eea 100644 --- a/osu.Game/Online/Multiplayer/GameType.cs +++ b/osu.Game/Online/Multiplayer/GameType.cs @@ -14,8 +14,6 @@ namespace osu.Game.Online.Multiplayer { public abstract string Name { get; } - public abstract bool IsAvailable { get; } - public abstract Drawable GetIcon(OsuColour colours, float size); public override int GetHashCode() => GetType().GetHashCode(); @@ -26,8 +24,6 @@ namespace osu.Game.Online.Multiplayer { public override string Name => "Tag"; - public override bool IsAvailable => false; - public override Drawable GetIcon(OsuColour colours, float size) { return new SpriteIcon @@ -46,8 +42,6 @@ namespace osu.Game.Online.Multiplayer { public override string Name => "Versus"; - public override bool IsAvailable => false; - public override Drawable GetIcon(OsuColour colours, float size) { return new VersusRow(colours.Blue, colours.Blue, size * 0.6f) @@ -62,8 +56,6 @@ namespace osu.Game.Online.Multiplayer { public override string Name => "Tag Team"; - public override bool IsAvailable => false; - public override Drawable GetIcon(OsuColour colours, float size) { return new FillFlowContainer @@ -98,8 +90,6 @@ namespace osu.Game.Online.Multiplayer { public override string Name => "Team Versus"; - public override bool IsAvailable => false; - public override Drawable GetIcon(OsuColour colours, float size) { return new FillFlowContainer @@ -166,8 +156,6 @@ namespace osu.Game.Online.Multiplayer { public override string Name => "Timeshift"; - public override bool IsAvailable => true; - public override Drawable GetIcon(OsuColour colours, float size) => new SpriteIcon { Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Multi/Components/DisableableTabControl.cs b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs new file mode 100644 index 0000000000..1ca61a2678 --- /dev/null +++ b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; + +namespace osu.Game.Screens.Multi.Components +{ + public abstract class DisableableTabControl : TabControl + { + public IEnumerable DisabledItems + { + set + { + foreach (var item in value) + (TabMap[item] as DisableableTabItem)?.Disable(); + } + } + + protected abstract class DisableableTabItem : TabItem + { + protected DisableableTabItem(T value) + : base(value) + { + } + + private bool isDisabled; + + public void Disable() + { + Alpha = 0.2f; + isDisabled = true; + } + + protected override bool OnClick(ClickEvent e) + { + if (isDisabled) + return true; + return base.OnClick(e); + } + } + } +} diff --git a/osu.Game/Screens/Multi/Components/GameTypePicker.cs b/osu.Game/Screens/Multi/Components/GameTypePicker.cs index 9cd1a7dc14..d9619ad35d 100644 --- a/osu.Game/Screens/Multi/Components/GameTypePicker.cs +++ b/osu.Game/Screens/Multi/Components/GameTypePicker.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.Multi.Components { - public class GameTypePicker : TabControl + public class GameTypePicker : DisableableTabControl { private const float height = 40; private const float selection_width = 3; @@ -34,7 +34,7 @@ namespace osu.Game.Screens.Multi.Components AddItem(new GameTypeTimeshift()); } - private class GameTypePickerItem : TabItem + private class GameTypePickerItem : DisableableTabItem { private const float transition_duration = 200; @@ -84,9 +84,6 @@ namespace osu.Game.Screens.Multi.Components private void load(OsuColour colours) { selection.Colour = colours.Yellow; - - if (!Value.IsAvailable) - Colour = colours.Gray5; } protected override bool OnHover(HoverEvent e) @@ -101,13 +98,6 @@ namespace osu.Game.Screens.Multi.Components base.OnHoverLost(e); } - protected override bool OnClick(ClickEvent e) - { - if (!Value.IsAvailable) - return true; - return base.OnClick(e); - } - protected override void OnActivated() { selection.FadeIn(transition_duration, Easing.OutQuint); diff --git a/osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs b/osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs index f0a2a2e8dc..287add5de1 100644 --- a/osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs +++ b/osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Multi.Components { - public class RoomAvailabilityPicker : TabControl + public class RoomAvailabilityPicker : DisableableTabControl { protected override TabItem CreateTabItem(RoomAvailability value) => new RoomAvailabilityPickerItem(value); protected override Dropdown CreateDropdown() => null; @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Multi.Components AddItem(RoomAvailability.InviteOnly); } - private class RoomAvailabilityPickerItem : TabItem + private class RoomAvailabilityPickerItem : DisableableTabItem { private const float transition_duration = 200; @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Multi.Components public RoomAvailabilityPickerItem(RoomAvailability value) : base(value) { RelativeSizeAxes = Axes.Y; - Width = 120; + Width = 102; Masking = true; CornerRadius = 5; diff --git a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs index f50eefe4c6..99afc437d0 100644 --- a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs @@ -125,6 +125,8 @@ namespace osu.Game.Screens.Multi.Components RelativeSizeAxes = Axes.X, TabbableContentContainer = this, OnCommit = (sender, text) => apply(), + Alpha = 0.2f, + ReadOnly = true, }, }, }, @@ -149,6 +151,21 @@ namespace osu.Game.Screens.Multi.Components typeBind.ValueChanged += t => TypePicker.Current.Value = t; maxParticipantsBind.ValueChanged += m => MaxParticipantsField.Text = m?.ToString(); + AvailabilityPicker.DisabledItems = new[] + { + RoomAvailability.FriendsOnly, + RoomAvailability.InviteOnly + }; + + TypePicker.DisabledItems = new GameType[] + { + new GameTypeTag(), + new GameTypeVersus(), + new GameTypeTagTeam(), + new GameTypeTeamVersus(), + }; + + Room = new Room(); } From 1a3c06f2d9bd86ea37789705e79e615045e3c66f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Dec 2018 20:19:21 +0900 Subject: [PATCH 016/220] Fix OsuTestCase beatmap not having a correct default beatmap --- osu.Game/Tests/Visual/OsuTestCase.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 67a13bd850..80c9b2ab47 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -29,6 +29,9 @@ namespace osu.Game.Tests.Visual { Dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + // This is the earliest we can get OsuGameBase, which is used by the dummy working beatmap to find textures + beatmap.Default = new DummyWorkingBeatmap(Dependencies.Get()); + Dependencies.CacheAs(beatmap); Dependencies.CacheAs(beatmap); From 5f0bde581c5ad5b07f5b601f5712363a29e489ae Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Dec 2018 20:42:16 +0900 Subject: [PATCH 017/220] Fix OsuBindableBeatmap not being able to be auto-constructed --- osu.Game/OsuGameBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 2729676504..28d5c557bc 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -259,7 +259,7 @@ namespace osu.Game RegisterAudioManager(audioManager); } - private OsuBindableBeatmap(WorkingBeatmap defaultValue) + public OsuBindableBeatmap(WorkingBeatmap defaultValue) : base(defaultValue) { } From eadbe4c4709a8730c01730a87c51cdf2f492da70 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Dec 2018 12:21:30 +0900 Subject: [PATCH 018/220] Make beatmap selection work --- osu.Game.Tests/Visual/TestCaseMatchHeader.cs | 43 ---------------- .../UpdateableBeatmapBackgroundSprite.cs | 50 +++++++++++++++++++ .../Screens/Multi/Components/DrawableRoom.cs | 22 +++++--- .../Screens/Multi/Components/RoomInspector.cs | 28 ++++++----- .../Screens/Multi/Screens/Match/Header.cs | 15 +++--- osu.Game/Screens/Multi/Screens/Match/Match.cs | 24 ++++++--- 6 files changed, 106 insertions(+), 76 deletions(-) delete mode 100644 osu.Game.Tests/Visual/TestCaseMatchHeader.cs create mode 100644 osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchHeader.cs b/osu.Game.Tests/Visual/TestCaseMatchHeader.cs deleted file mode 100644 index 34f98f97c2..0000000000 --- a/osu.Game.Tests/Visual/TestCaseMatchHeader.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using NUnit.Framework; -using osu.Game.Beatmaps; -using osu.Game.Screens.Multi.Screens.Match; - -namespace osu.Game.Tests.Visual -{ - [TestFixture] - public class TestCaseMatchHeader : OsuTestCase - { - public TestCaseMatchHeader() - { - Header header = new Header(); - Add(header); - - AddStep(@"set beatmap set", () => header.BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/760757/covers/cover.jpg?1526944540", - }, - }, - }); - - AddStep(@"change beatmap set", () => header.BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/761883/covers/cover.jpg?1525557400", - }, - }, - }); - - AddStep(@"null beatmap set", () => header.BeatmapSet = null); - } - } -} diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs new file mode 100644 index 0000000000..5ced21e436 --- /dev/null +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; + +namespace osu.Game.Beatmaps.Drawables +{ + public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable + { + public readonly IBindable Beatmap = new Bindable(); + + [Resolved] + private OsuGameBase game { get; set; } + + public UpdateableBeatmapBackgroundSprite() + { + Beatmap.BindValueChanged(b => Schedule(() => Model = b)); + } + + protected override Drawable CreateDrawable(WorkingBeatmap model) + { + Drawable drawable = model == null ? (Drawable)new DefaultSprite() : new BeatmapBackgroundSprite(model); + + drawable.RelativeSizeAxes = Axes.Both; + drawable.Anchor = Anchor.Centre; + drawable.Origin = Anchor.Centre; + drawable.FillMode = FillMode.Fill; + + return drawable; + } + + protected override double FadeDuration => 400; + + private class DefaultSprite : Sprite + { + [Resolved] + private IBindableBeatmap gameBeatmap { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + Texture = gameBeatmap.Default.Background; + } + } + } +} diff --git a/osu.Game/Screens/Multi/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Components/DrawableRoom.cs index 2f26f53e8b..30bee7829e 100644 --- a/osu.Game/Screens/Multi/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Components/DrawableRoom.cs @@ -44,9 +44,14 @@ namespace osu.Game.Screens.Multi.Components private readonly Bindable hostBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); - private readonly Bindable beatmapBind = new Bindable(); + private readonly Bindable roomBeatmap = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); + private readonly Bindable beatmap = new Bindable(); + + [Resolved] + private BeatmapManager beatmaps { get; set; } + public readonly Room Room; private SelectionState state; @@ -101,7 +106,7 @@ namespace osu.Game.Screens.Multi.Components private void load(OsuColour colours) { Box sideStrip; - UpdateableBeatmapSetCover cover; + UpdateableBeatmapBackgroundSprite background; OsuSpriteText name, status; ParticipantInfo participantInfo; BeatmapTitle beatmapTitle; @@ -137,12 +142,13 @@ namespace osu.Game.Screens.Multi.Components RelativeSizeAxes = Axes.Y, Width = side_strip_width, }, - cover = new UpdateableBeatmapSetCover + new Container { - Width = cover_width, RelativeSizeAxes = Axes.Y, + Width = cover_width, Masking = true, Margin = new MarginPadding { Left = side_strip_width }, + Child = background = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both } }, new Container { @@ -216,9 +222,11 @@ namespace osu.Game.Screens.Multi.Components d.FadeColour(s.GetAppropriateColour(colours), transition_duration); }; - beatmapBind.ValueChanged += b => + background.Beatmap.BindTo(beatmap); + + roomBeatmap.ValueChanged += b => { - cover.BeatmapSet = b?.BeatmapSet; + beatmap.Value = beatmaps.GetWorkingBeatmap(b); beatmapTitle.Beatmap = b; modeTypeInfo.Beatmap = b; }; @@ -227,7 +235,7 @@ namespace osu.Game.Screens.Multi.Components hostBind.BindTo(Room.Host); statusBind.BindTo(Room.Status); typeBind.BindTo(Room.Type); - beatmapBind.BindTo(Room.Beatmap); + roomBeatmap.BindTo(Room.Beatmap); participantsBind.BindTo(Room.Participants); } diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs index 1ec509d5a8..b7dcb3c8fb 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -32,13 +32,15 @@ namespace osu.Game.Screens.Multi.Components private readonly Bindable hostBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); - private readonly Bindable beatmapBind = new Bindable(); + private readonly Bindable roomBeatmap = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); + private readonly Bindable beatmap = new Bindable(); + private OsuColour colours; private Box statusStrip; - private UpdateableBeatmapSetCover cover; + private UpdateableBeatmapBackgroundSprite background; private ParticipantCount participantCount; private FillFlowContainer topFlow, participantsFlow; private OsuSpriteText name, status; @@ -46,6 +48,9 @@ namespace osu.Game.Screens.Multi.Components private ScrollContainer participantsScroll; private ParticipantInfo participantInfo; + [Resolved] + private BeatmapManager beatmaps { get; set; } + private Room room; public Room Room { @@ -59,7 +64,7 @@ namespace osu.Game.Screens.Multi.Components hostBind.UnbindBindings(); statusBind.UnbindBindings(); typeBind.UnbindBindings(); - beatmapBind.UnbindBindings(); + roomBeatmap.UnbindBindings(); maxParticipantsBind.UnbindBindings(); participantsBind.UnbindBindings(); @@ -69,7 +74,7 @@ namespace osu.Game.Screens.Multi.Components hostBind.BindTo(room.Host); statusBind.BindTo(room.Status); typeBind.BindTo(room.Type); - beatmapBind.BindTo(room.Beatmap); + roomBeatmap.BindTo(room.Beatmap); maxParticipantsBind.BindTo(room.MaxParticipants); participantsBind.BindTo(room.Participants); } @@ -104,10 +109,7 @@ namespace osu.Game.Screens.Multi.Components Masking = true, Children = new Drawable[] { - cover = new UpdateableBeatmapSetCover - { - RelativeSizeAxes = Axes.Both, - }, + background = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both }, new Box { RelativeSizeAxes = Axes.Both, @@ -207,9 +209,11 @@ namespace osu.Game.Screens.Multi.Components maxParticipantsBind.ValueChanged += m => participantCount.Max = m; statusBind.ValueChanged += displayStatus; - beatmapBind.ValueChanged += b => + background.Beatmap.BindTo(beatmap); + + roomBeatmap.ValueChanged += b => { - cover.BeatmapSet = b?.BeatmapSet; + beatmap.Value = beatmaps.GetWorkingBeatmap(b); beatmapTypeInfo.Beatmap = b; }; @@ -243,7 +247,7 @@ namespace osu.Game.Screens.Multi.Components { if (Room == null) { - cover.BeatmapSet = null; + beatmap.Value = null; participantsFlow.FadeOut(transition_duration); participantCount.FadeOut(transition_duration); beatmapTypeInfo.FadeOut(transition_duration); @@ -261,7 +265,7 @@ namespace osu.Game.Screens.Multi.Components participantInfo.FadeIn(transition_duration); statusBind.TriggerChange(); - beatmapBind.TriggerChange(); + roomBeatmap.TriggerChange(); } } diff --git a/osu.Game/Screens/Multi/Screens/Match/Header.cs b/osu.Game/Screens/Multi/Screens/Match/Header.cs index c2de50fa65..e4a7baf035 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Header.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Header.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -24,16 +25,12 @@ namespace osu.Game.Screens.Multi.Screens.Match { public const float HEIGHT = 200; + public readonly IBindable Beatmap = new Bindable(); + private readonly Box tabStrip; - private readonly UpdateableBeatmapSetCover cover; public readonly PageTabControl Tabs; - public BeatmapSetInfo BeatmapSet - { - set => cover.BeatmapSet = value; - } - public Action OnRequestSelectBeatmap; public Header() @@ -42,12 +39,14 @@ namespace osu.Game.Screens.Multi.Screens.Match Height = HEIGHT; BeatmapSelectButton beatmapButton; + UpdateableBeatmapBackgroundSprite background; Children = new Drawable[] { - cover = new UpdateableBeatmapSetCover + new Container { RelativeSizeAxes = Axes.Both, Masking = true, + Child = background = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both } }, new Box { @@ -90,6 +89,8 @@ namespace osu.Game.Screens.Multi.Screens.Match }; beatmapButton.Action = () => OnRequestSelectBeatmap?.Invoke(); + + background.Beatmap.BindTo(Beatmap); } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs index 2dbe0a9c3a..468390b75b 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -22,19 +23,24 @@ namespace osu.Game.Screens.Multi.Screens.Match private readonly Bindable statusBind = new Bindable(); private readonly Bindable availabilityBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); - private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); + private readonly Bindable roomBeatmap = new Bindable(); + protected override Container TransitionContent => participants; public override string Title => room.Name.Value; public override string ShortTitle => "room"; + [Resolved] + private BeatmapManager beatmapManager { get; set; } + public Match(Room room) { this.room = room; + Header header; RoomSettingsOverlay settings; Info info; @@ -68,13 +74,9 @@ namespace osu.Game.Screens.Multi.Screens.Match }; header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect()); + header.Beatmap.BindTo(Beatmap); - beatmapBind.BindTo(room.Beatmap); - beatmapBind.BindValueChanged(b => - { - header.BeatmapSet = b?.BeatmapSet; - info.Beatmap = b; - }, true); + roomBeatmap.BindValueChanged(b => info.Beatmap = b, true); header.Tabs.Current.ValueChanged += t => { @@ -110,5 +112,13 @@ namespace osu.Game.Screens.Multi.Screens.Match participantsBind.BindTo(room.Participants); participantsBind.BindValueChanged(p => participants.Users = p, true); } + + [BackgroundDependencyLoader] + private void load() + { + roomBeatmap.BindTo(room.Beatmap); + roomBeatmap.BindValueChanged(b => Beatmap.Value = beatmapManager.GetWorkingBeatmap(room.Beatmap.Value), true); + Beatmap.BindValueChanged(b => roomBeatmap.Value = b.BeatmapInfo); + } } } From 42817b98f9ed6bb1081d65662992116a03fffb75 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Dec 2018 18:16:17 +0900 Subject: [PATCH 019/220] Hide max participants box --- osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 3 ++- osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index af41563e30..463002fbcb 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Testing.Input; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Components; @@ -38,9 +39,9 @@ namespace osu.Game.Tests.Visual { RelativeSizeAxes = Axes.Both, Height = 0.75f, + State = Visibility.Visible }); - AddStep(@"show", overlay.Show); assertAll(); AddStep(@"set name", () => overlay.CurrentName = @"Two Testing Room"); AddStep(@"set max", () => overlay.CurrentMaxParticipants = null); diff --git a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs index 99afc437d0..467b936538 100644 --- a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs @@ -33,6 +33,7 @@ namespace osu.Game.Screens.Multi.Components private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Container content; + private readonly OsuSpriteText typeLabel; protected readonly OsuTextBox NameField, MaxParticipantsField; @@ -115,6 +116,8 @@ namespace osu.Game.Screens.Multi.Components { RelativeSizeAxes = Axes.X, TabbableContentContainer = this, + Alpha = 0.2f, + ReadOnly = true, OnCommit = (sender, text) => apply(), }, }, From c02150a19b816955a5222159508a30b07b19d829 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Dec 2018 18:31:12 +0900 Subject: [PATCH 020/220] Make match header not fade when beatmap changes --- osu.Game.Tests/Visual/TestCaseMatch.cs | 3 ++- osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs | 1 - osu.Game/Screens/Multi/Screens/Match/Header.cs | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatch.cs b/osu.Game.Tests/Visual/TestCaseMatch.cs index ae19b9720e..6099ed41bb 100644 --- a/osu.Game.Tests/Visual/TestCaseMatch.cs +++ b/osu.Game.Tests/Visual/TestCaseMatch.cs @@ -20,7 +20,8 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(TestCaseMatch), - typeof(GameTypePicker) + typeof(GameTypePicker), + typeof(RoomSettingsOverlay) }; [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs index 467b936538..bd9b269452 100644 --- a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs @@ -168,7 +168,6 @@ namespace osu.Game.Screens.Multi.Components new GameTypeTeamVersus(), }; - Room = new Room(); } diff --git a/osu.Game/Screens/Multi/Screens/Match/Header.cs b/osu.Game/Screens/Multi/Screens/Match/Header.cs index e4a7baf035..50db63e3e3 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Header.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Header.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Multi.Screens.Match { RelativeSizeAxes = Axes.Both, Masking = true, - Child = background = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both } + Child = background = new HeaderBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both } }, new Box { @@ -175,6 +175,11 @@ namespace osu.Game.Screens.Multi.Screens.Match return base.OnMouseUp(e); } } + + private class HeaderBeatmapBackgroundSprite : UpdateableBeatmapBackgroundSprite + { + protected override double FadeDuration => 0; + } } public enum MatchHeaderPage From d68b4bb8e7809a704755373dff76fb61a49a863c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Dec 2018 14:28:43 +0900 Subject: [PATCH 021/220] Remove custom action from DrawableRoom --- osu.Game/Screens/Multi/Components/DrawableRoom.cs | 9 --------- osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Components/DrawableRoom.cs index 30bee7829e..6bdc4c2f2d 100644 --- a/osu.Game/Screens/Multi/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Components/DrawableRoom.cs @@ -10,7 +10,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; @@ -36,8 +35,6 @@ namespace osu.Game.Screens.Multi.Components public event Action StateChanged; - public Action SelectionRequested; - private readonly Box selectionBox; private readonly Bindable nameBind = new Bindable(); @@ -244,11 +241,5 @@ namespace osu.Game.Screens.Multi.Components base.LoadComplete(); this.FadeInFromZero(transition_duration); } - - protected override bool OnClick(ClickEvent e) - { - SelectionRequested?.Invoke(); - return true; - } } } diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index f307032600..f4dd45bdfb 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -117,7 +117,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { var drawableRoom = new DrawableRoom(room); - drawableRoom.SelectionRequested = () => selectionRequested(drawableRoom); + drawableRoom.Action = () => selectionRequested(drawableRoom); RoomsContainer.Add(drawableRoom); From 29263d71544c9613c8c14f71c4f36ed0d775a8f2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Dec 2018 16:20:05 +0900 Subject: [PATCH 022/220] Refactor bindable shenanigans in Match --- osu.Game.Tests/Visual/TestCaseMatchInfo.cs | 22 +++--- .../Visual/TestCaseMatchParticipants.cs | 10 +-- .../Screens/Multi/Screens/Lounge/Lounge.cs | 2 +- osu.Game/Screens/Multi/Screens/Match/Info.cs | 67 ++++++------------- osu.Game/Screens/Multi/Screens/Match/Match.cs | 44 ++++++------ .../Multi/Screens/Match/Participants.cs | 48 +++++++------ .../Multi/Screens/MultiplayerScreen.cs | 3 +- 7 files changed, 85 insertions(+), 111 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs index 205da6932f..6998ff4c39 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs @@ -19,10 +19,10 @@ namespace osu.Game.Tests.Visual Info info = new Info(); Add(info); - AddStep(@"set name", () => info.Name = @"Room Name?"); - AddStep(@"set availability", () => info.Availability = RoomAvailability.FriendsOnly); - AddStep(@"set status", () => info.Status = new RoomStatusPlaying()); - AddStep(@"set beatmap", () => info.Beatmap = new BeatmapInfo + AddStep(@"set name", () => info.Name.Value = @"Room Name?"); + AddStep(@"set availability", () => info.Availability.Value = RoomAvailability.FriendsOnly); + AddStep(@"set status", () => info.Status.Value = new RoomStatusPlaying()); + AddStep(@"set beatmap", () => info.Beatmap.Value = new BeatmapInfo { StarDifficulty = 2.4, Ruleset = rulesets.GetRuleset(0), @@ -34,14 +34,14 @@ namespace osu.Game.Tests.Visual }, }); - AddStep(@"set type", () => info.Type = new GameTypeTagTeam()); + AddStep(@"set type", () => info.Type.Value = new GameTypeTagTeam()); - AddStep(@"change name", () => info.Name = @"Room Name!"); - AddStep(@"change availability", () => info.Availability = RoomAvailability.InviteOnly); - AddStep(@"change status", () => info.Status = new RoomStatusOpen()); - AddStep(@"null beatmap", () => info.Beatmap = null); - AddStep(@"change type", () => info.Type = new GameTypeTeamVersus()); - AddStep(@"change beatmap", () => info.Beatmap = new BeatmapInfo + AddStep(@"change name", () => info.Name.Value = @"Room Name!"); + AddStep(@"change availability", () => info.Availability.Value = RoomAvailability.InviteOnly); + AddStep(@"change status", () => info.Status.Value = new RoomStatusOpen()); + AddStep(@"null beatmap", () => info.Beatmap.Value = null); + AddStep(@"change type", () => info.Type.Value = new GameTypeTeamVersus()); + AddStep(@"change beatmap", () => info.Beatmap.Value = new BeatmapInfo { StarDifficulty = 4.2, Ruleset = rulesets.GetRuleset(3), diff --git a/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs index d6ae07252b..6024ec8ea6 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs @@ -19,8 +19,8 @@ namespace osu.Game.Tests.Visual RelativeSizeAxes = Axes.Both, }); - AddStep(@"set max to null", () => participants.Max = null); - AddStep(@"set users", () => participants.Users = new[] + AddStep(@"set max to null", () => participants.MaxParticipants.Value = null); + AddStep(@"set users", () => participants.Users.Value = new[] { new User { @@ -48,9 +48,9 @@ namespace osu.Game.Tests.Visual }, }); - AddStep(@"set max", () => participants.Max = 10); - AddStep(@"clear users", () => participants.Users = new User[] { }); - AddStep(@"set max to null", () => participants.Max = null); + AddStep(@"set max", () => participants.MaxParticipants.Value = 10); + AddStep(@"clear users", () => participants.Users.Value = new User[] { }); + AddStep(@"set max to null", () => participants.MaxParticipants.Value = null); } } } diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index f4dd45bdfb..140b3550c1 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge public override string Title => "Lounge"; - protected override Container TransitionContent => content; + protected override Drawable TransitionContent => content; public Lounge() { diff --git a/osu.Game/Screens/Multi/Screens/Match/Info.cs b/osu.Game/Screens/Multi/Screens/Match/Info.cs index a2c056c8bd..fc6e84c38a 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Info.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Info.cs @@ -23,60 +23,26 @@ namespace osu.Game.Screens.Multi.Screens.Match { public const float HEIGHT = 128; - private readonly OsuSpriteText name, availabilityStatus; - private readonly BeatmapTypeInfo beatmapTypeInfo; + private readonly OsuSpriteText availabilityStatus; private readonly ReadyButton readyButton; private OsuColour colours; public Bindable Ready => readyButton.Ready; - public string Name - { - set { name.Text = value; } - } - - private RoomAvailability availability; - public RoomAvailability Availability - { - set - { - if (value == availability) return; - availability = value; - - if (IsLoaded) - updateAvailabilityStatus(); - } - } - - private RoomStatus status; - public RoomStatus Status - { - set - { - if (value == status) return; - status = value; - - if (IsLoaded) - updateAvailabilityStatus(); - } - } - - public BeatmapInfo Beatmap - { - set { beatmapTypeInfo.Beatmap = value; } - } - - public GameType Type - { - set { beatmapTypeInfo.Type = value; } - } + public readonly Bindable Name = new Bindable(); + public readonly Bindable Availability = new Bindable(); + public readonly Bindable Status = new Bindable(); + public readonly Bindable Beatmap = new Bindable(); + public readonly Bindable Type = new Bindable(); public Info() { RelativeSizeAxes = Axes.X; Height = HEIGHT; + BeatmapTypeInfo beatmapTypeInfo; + Children = new Drawable[] { new Box @@ -103,9 +69,10 @@ namespace osu.Game.Screens.Multi.Screens.Match Direction = FillDirection.Vertical, Children = new Drawable[] { - name = new OsuSpriteText + new OsuSpriteText { TextSize = 30, + Current = Name }, availabilityStatus = new OsuSpriteText { @@ -131,6 +98,11 @@ namespace osu.Game.Screens.Multi.Screens.Match }, }, }; + + Availability.BindValueChanged(_ => updateAvailabilityStatus()); + Status.BindValueChanged(_ => updateAvailabilityStatus()); + Beatmap.BindValueChanged(b => beatmapTypeInfo.Beatmap = b); + Type.BindValueChanged(t => beatmapTypeInfo.Type = t); } [BackgroundDependencyLoader] @@ -148,10 +120,13 @@ namespace osu.Game.Screens.Multi.Screens.Match private void updateAvailabilityStatus() { - if (status != null) + if (!IsLoaded) + return; + + if (Status.Value != null) { - availabilityStatus.FadeColour(status.GetAppropriateColour(colours), 100); - availabilityStatus.Text = $"{availability.GetDescription()}, {status.Message}"; + availabilityStatus.FadeColour(Status.Value.GetAppropriateColour(colours), 100); + availabilityStatus.Text = $"{Availability.Value.GetDescription()}, {Status.Value.Message}"; } } diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs index 468390b75b..4f81ffd305 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -20,15 +20,14 @@ namespace osu.Game.Screens.Multi.Screens.Match private readonly Participants participants; private readonly Bindable nameBind = new Bindable(); + private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); private readonly Bindable availabilityBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); - private readonly Bindable roomBeatmap = new Bindable(); - - protected override Container TransitionContent => participants; + protected override Drawable TransitionContent => participants; public override string Title => room.Name.Value; @@ -41,6 +40,14 @@ namespace osu.Game.Screens.Multi.Screens.Match { this.room = room; + nameBind.BindTo(room.Name); + beatmapBind.BindTo(room.Beatmap); + statusBind.BindTo(room.Status); + availabilityBind.BindTo(room.Availability); + typeBind.BindTo(room.Type); + participantsBind.BindTo(room.Participants); + maxParticipantsBind.BindTo(room.MaxParticipants); + Header header; RoomSettingsOverlay settings; Info info; @@ -76,8 +83,6 @@ namespace osu.Game.Screens.Multi.Screens.Match header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect()); header.Beatmap.BindTo(Beatmap); - roomBeatmap.BindValueChanged(b => info.Beatmap = b, true); - header.Tabs.Current.ValueChanged += t => { if (t == MatchHeaderPage.Settings) @@ -94,31 +99,22 @@ namespace osu.Game.Screens.Multi.Screens.Match settings.Applied = () => settings.Hide(); - nameBind.BindTo(room.Name); - nameBind.BindValueChanged(n => info.Name = n, true); + info.Beatmap.BindTo(beatmapBind); + info.Name.BindTo(nameBind); + info.Status.BindTo(statusBind); + info.Availability.BindTo(availabilityBind); + info.Type.BindTo(typeBind); - statusBind.BindTo(room.Status); - statusBind.BindValueChanged(s => info.Status = s, true); - - availabilityBind.BindTo(room.Availability); - availabilityBind.BindValueChanged(a => info.Availability = a, true); - - typeBind.BindTo(room.Type); - typeBind.BindValueChanged(t => info.Type = t, true); - - maxParticipantsBind.BindTo(room.MaxParticipants); - maxParticipantsBind.BindValueChanged(m => { participants.Max = m; }, true); - - participantsBind.BindTo(room.Participants); - participantsBind.BindValueChanged(p => participants.Users = p, true); + participants.Users.BindTo(participantsBind); + participants.MaxParticipants.BindTo(maxParticipantsBind); } [BackgroundDependencyLoader] private void load() { - roomBeatmap.BindTo(room.Beatmap); - roomBeatmap.BindValueChanged(b => Beatmap.Value = beatmapManager.GetWorkingBeatmap(room.Beatmap.Value), true); - Beatmap.BindValueChanged(b => roomBeatmap.Value = b.BeatmapInfo); + beatmapBind.BindTo(room.Beatmap); + beatmapBind.BindValueChanged(b => Beatmap.Value = beatmapManager.GetWorkingBeatmap(room.Beatmap.Value), true); + Beatmap.BindValueChanged(b => beatmapBind.Value = b.BeatmapInfo); } } } diff --git a/osu.Game/Screens/Multi/Screens/Match/Participants.cs b/osu.Game/Screens/Multi/Screens/Match/Participants.cs index a5ac93fffc..d40796760b 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Participants.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Participants.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays.SearchableList; @@ -12,35 +13,23 @@ using osuTK; namespace osu.Game.Screens.Multi.Screens.Match { - public class Participants : Container + public class Participants : CompositeDrawable { - private readonly ParticipantCount count; - private readonly FillFlowContainer usersFlow; + public readonly Bindable> Users = new Bindable>(); + public readonly Bindable MaxParticipants = new Bindable(); - public IEnumerable Users + public new MarginPadding Padding { - set - { - usersFlow.Children = value.Select(u => new UserPanel(u) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Width = 300, - OnLoadComplete = d => d.FadeInFromZero(60), - }).ToList(); - - count.Count = value.Count(); - } - } - - public int? Max - { - set => count.Max = value; + get => base.Padding; + set => base.Padding = value; } public Participants() { - Child = new Container + FillFlowContainer usersFlow; + ParticipantCount count; + + InternalChild = new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, @@ -70,6 +59,21 @@ namespace osu.Game.Screens.Multi.Screens.Match }, }, }; + + Users.BindValueChanged(v => + { + usersFlow.Children = v.Select(u => new UserPanel(u) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Width = 300, + OnLoadComplete = d => d.FadeInFromZero(60), + }).ToList(); + + count.Count = v.Count(); + }); + + MaxParticipants.BindValueChanged(v => count.Max = v); } } } diff --git a/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs b/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs index fd866a5fef..3184316a33 100644 --- a/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs +++ b/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Graphics.Containers; @@ -10,7 +9,7 @@ namespace osu.Game.Screens.Multi.Screens { public abstract class MultiplayerScreen : OsuScreen, IMultiplayerScreen { - protected virtual Container TransitionContent => Content; + protected virtual Drawable TransitionContent => Content; public virtual string ShortTitle => Title; From feb1adb51db60553b75ad454eb0085f1742c00e9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Dec 2018 19:38:46 +0900 Subject: [PATCH 023/220] Use bindable propagation rather than properties --- .../Screens/Multi/Components/BeatmapTitle.cs | 42 +++++---- .../Multi/Components/BeatmapTypeInfo.cs | 65 +++++++------- .../Screens/Multi/Components/DrawableRoom.cs | 29 +++---- .../Screens/Multi/Components/ModeTypeInfo.cs | 85 +++++++------------ .../Multi/Components/ParticipantCount.cs | 76 ++++++++--------- .../Multi/Components/ParticipantInfo.cs | 41 +++++---- .../Screens/Multi/Components/RoomInspector.cs | 33 +++---- osu.Game/Screens/Multi/Screens/Match/Info.cs | 5 +- .../Multi/Screens/Match/Participants.cs | 7 +- 9 files changed, 177 insertions(+), 206 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index 6dc59f5cac..e3ef5eb401 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; @@ -9,7 +10,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Multi.Components { - public class BeatmapTitle : FillFlowContainer + public class BeatmapTitle : CompositeDrawable { private readonly OsuSpriteText beatmapTitle, beatmapDash, beatmapArtist; @@ -18,31 +19,25 @@ namespace osu.Game.Screens.Multi.Components set { beatmapTitle.TextSize = beatmapDash.TextSize = beatmapArtist.TextSize = value; } } - private BeatmapInfo beatmap; - - public BeatmapInfo Beatmap - { - set - { - if (value == beatmap) return; - beatmap = value; - - if (IsLoaded) - updateText(); - } - } + public readonly Bindable Beatmap = new Bindable(); public BeatmapTitle() { AutoSizeAxes = Axes.Both; - Direction = FillDirection.Horizontal; - Children = new[] + InternalChild = new FillFlowContainer { - beatmapTitle = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", }, - beatmapDash = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", }, - beatmapArtist = new OsuSpriteText { Font = @"Exo2.0-RegularItalic", }, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new[] + { + beatmapTitle = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", }, + beatmapDash = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", }, + beatmapArtist = new OsuSpriteText { Font = @"Exo2.0-RegularItalic", }, + } }; + + Beatmap.BindValueChanged(v => updateText()); } protected override void LoadComplete() @@ -53,16 +48,19 @@ namespace osu.Game.Screens.Multi.Components private void updateText() { - if (beatmap == null) + if (!IsLoaded) + return; + + if (Beatmap.Value == null) { beatmapTitle.Text = "Changing map"; beatmapDash.Text = beatmapArtist.Text = string.Empty; } else { - beatmapTitle.Text = new LocalisedString((beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title)); + beatmapTitle.Text = new LocalisedString((Beatmap.Value.Metadata.TitleUnicode, Beatmap.Value.Metadata.Title)); beatmapDash.Text = @" - "; - beatmapArtist.Text = new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)); + beatmapArtist.Text = new LocalisedString((Beatmap.Value.Metadata.ArtistUnicode, Beatmap.Value.Metadata.Artist)); } } } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs index a22e171275..2bd7b19a0a 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; @@ -12,53 +13,55 @@ using osuTK; namespace osu.Game.Screens.Multi.Components { - public class BeatmapTypeInfo : FillFlowContainer + public class BeatmapTypeInfo : CompositeDrawable { - private readonly ModeTypeInfo modeTypeInfo; - private readonly BeatmapTitle beatmapTitle; private readonly OsuSpriteText beatmapAuthor; - public BeatmapInfo Beatmap - { - set - { - modeTypeInfo.Beatmap = beatmapTitle.Beatmap = value; - beatmapAuthor.Text = value == null ? string.Empty : $"mapped by {value.Metadata.Author}"; - } - } + public readonly Bindable Beatmap = new Bindable(); - public GameType Type - { - set { modeTypeInfo.Type = value; } - } + public readonly Bindable Type = new Bindable(); public BeatmapTypeInfo() { AutoSizeAxes = Axes.Both; - Direction = FillDirection.Horizontal; - LayoutDuration = 100; - Spacing = new Vector2(5f, 0f); - Children = new Drawable[] + BeatmapTitle beatmapTitle; + ModeTypeInfo modeTypeInfo; + + InternalChild = new FillFlowContainer { - modeTypeInfo = new ModeTypeInfo(), - new Container + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + LayoutDuration = 100, + Spacing = new Vector2(5, 0), + Children = new Drawable[] { - AutoSizeAxes = Axes.X, - Height = 30, - Margin = new MarginPadding { Left = 5 }, - Children = new Drawable[] + modeTypeInfo = new ModeTypeInfo(), + new Container { - beatmapTitle = new BeatmapTitle(), - beatmapAuthor = new OsuSpriteText + AutoSizeAxes = Axes.X, + Height = 30, + Margin = new MarginPadding { Left = 5 }, + Children = new Drawable[] { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - TextSize = 14, + beatmapTitle = new BeatmapTitle(), + beatmapAuthor = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + TextSize = 14, + }, }, }, - }, + } }; + + modeTypeInfo.Beatmap.BindTo(Beatmap); + modeTypeInfo.Type.BindTo(Type); + + beatmapTitle.Beatmap.BindTo(Beatmap); + + Beatmap.BindValueChanged(v => beatmapAuthor.Text = v == null ? string.Empty : $"mapped by {v.Metadata.Author}"); } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Components/DrawableRoom.cs index 6bdc4c2f2d..43a9b6ad06 100644 --- a/osu.Game/Screens/Multi/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Components/DrawableRoom.cs @@ -38,10 +38,10 @@ namespace osu.Game.Screens.Multi.Components private readonly Box selectionBox; private readonly Bindable nameBind = new Bindable(); + private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable hostBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); - private readonly Bindable roomBeatmap = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); private readonly Bindable beatmap = new Bindable(); @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Multi.Components { Box sideStrip; UpdateableBeatmapBackgroundSprite background; - OsuSpriteText name, status; + OsuSpriteText status; ParticipantInfo participantInfo; BeatmapTitle beatmapTitle; ModeTypeInfo modeTypeInfo; @@ -166,9 +166,10 @@ namespace osu.Game.Screens.Multi.Components Spacing = new Vector2(5f), Children = new Drawable[] { - name = new OsuSpriteText + new OsuSpriteText { TextSize = 18, + Current = nameBind }, participantInfo = new ParticipantInfo(), }, @@ -206,11 +207,6 @@ namespace osu.Game.Screens.Multi.Components }, }; - nameBind.ValueChanged += n => name.Text = n; - hostBind.ValueChanged += h => participantInfo.Host = h; - typeBind.ValueChanged += m => modeTypeInfo.Type = m; - participantsBind.ValueChanged += p => participantInfo.Participants = p; - statusBind.ValueChanged += s => { status.Text = s.Message; @@ -221,19 +217,22 @@ namespace osu.Game.Screens.Multi.Components background.Beatmap.BindTo(beatmap); - roomBeatmap.ValueChanged += b => - { - beatmap.Value = beatmaps.GetWorkingBeatmap(b); - beatmapTitle.Beatmap = b; - modeTypeInfo.Beatmap = b; - }; + beatmapBind.ValueChanged += b => beatmap.Value = beatmaps.GetWorkingBeatmap(b); nameBind.BindTo(Room.Name); hostBind.BindTo(Room.Host); statusBind.BindTo(Room.Status); typeBind.BindTo(Room.Type); - roomBeatmap.BindTo(Room.Beatmap); + beatmapBind.BindTo(Room.Beatmap); participantsBind.BindTo(Room.Participants); + + modeTypeInfo.Beatmap.BindTo(beatmapBind); + modeTypeInfo.Type.BindTo(typeBind); + + participantInfo.Host.BindTo(hostBind); + participantInfo.Participants.BindTo(participantsBind); + + beatmapTitle.Beatmap.BindTo(beatmapBind); } protected override void LoadComplete() diff --git a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 95f0c2153d..87d150c5a4 100644 --- a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; @@ -10,74 +11,54 @@ using osuTK; namespace osu.Game.Screens.Multi.Components { - public class ModeTypeInfo : Container + public class ModeTypeInfo : CompositeDrawable { private const float height = 30; private const float transition_duration = 100; - private readonly Container rulesetContainer, gameTypeContainer; + private readonly Container rulesetContainer; - public BeatmapInfo Beatmap - { - set - { - if (value != null) - { - rulesetContainer.FadeIn(transition_duration); - rulesetContainer.Children = new[] - { - new DifficultyIcon(value) - { - Size = new Vector2(height), - }, - }; - } - else - { - rulesetContainer.FadeOut(transition_duration); - } - } - } - - public GameType Type - { - set - { - gameTypeContainer.Children = new[] - { - new DrawableGameType(value) - { - Size = new Vector2(height), - }, - }; - } - } + public readonly Bindable Beatmap = new Bindable(); + public readonly Bindable Type = new Bindable(); public ModeTypeInfo() { AutoSizeAxes = Axes.Both; - Children = new[] + Container gameTypeContainer; + + InternalChild = new FillFlowContainer { - new FillFlowContainer + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5f, 0f), + LayoutDuration = 100, + Children = new[] { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5f, 0f), - LayoutDuration = 100, - Children = new[] + rulesetContainer = new Container { - rulesetContainer = new Container - { - AutoSizeAxes = Axes.Both, - }, - gameTypeContainer = new Container - { - AutoSizeAxes = Axes.Both, - }, + AutoSizeAxes = Axes.Both, + }, + gameTypeContainer = new Container + { + AutoSizeAxes = Axes.Both, }, }, }; + + Beatmap.BindValueChanged(updateBeatmap); + Type.BindValueChanged(v => gameTypeContainer.Child = new DrawableGameType(v) { Size = new Vector2(height) }); + } + + private void updateBeatmap(BeatmapInfo beatmap) + { + if (beatmap != null) + { + rulesetContainer.FadeIn(transition_duration); + rulesetContainer.Child = new DifficultyIcon(beatmap) { Size = new Vector2(height) }; + } + else + rulesetContainer.FadeOut(transition_duration); } } } diff --git a/osu.Game/Screens/Multi/Components/ParticipantCount.cs b/osu.Game/Screens/Multi/Components/ParticipantCount.cs index e7183cbd92..66f13ed683 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantCount.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantCount.cs @@ -1,69 +1,65 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Users; namespace osu.Game.Screens.Multi.Components { - public class ParticipantCount : FillFlowContainer + public class ParticipantCount : CompositeDrawable { private const float text_size = 30; private const float transition_duration = 100; - private readonly OsuSpriteText count, slash, maxText; + private readonly OsuSpriteText slash, maxText; - public int Count - { - set => count.Text = value.ToString(); - } - - private int? max; - public int? Max - { - get => max; - set - { - if (value == max) return; - max = value; - - updateMax(); - } - } + public readonly Bindable> Participants = new Bindable>(); + public readonly Bindable MaxParticipants = new Bindable(); public ParticipantCount() { AutoSizeAxes = Axes.Both; - Direction = FillDirection.Horizontal; - LayoutDuration = transition_duration; - Children = new[] + OsuSpriteText count; + + InternalChild = new FillFlowContainer { - count = new OsuSpriteText + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + LayoutDuration = transition_duration, + Children = new[] { - TextSize = text_size, - Font = @"Exo2.0-Bold" - }, - slash = new OsuSpriteText - { - Text = @"/", - TextSize = text_size, - Font = @"Exo2.0-Light" - }, - maxText = new OsuSpriteText - { - TextSize = text_size, - Font = @"Exo2.0-Light" - }, + count = new OsuSpriteText + { + TextSize = text_size, + Font = @"Exo2.0-Bold" + }, + slash = new OsuSpriteText + { + Text = @"/", + TextSize = text_size, + Font = @"Exo2.0-Light" + }, + maxText = new OsuSpriteText + { + TextSize = text_size, + Font = @"Exo2.0-Light" + }, + } }; - updateMax(); + Participants.BindValueChanged(v => count.Text = v.Count().ToString()); + MaxParticipants.BindValueChanged(_ => updateMax(), true); } private void updateMax() { - if (Max == null) + if (MaxParticipants.Value == null) { slash.FadeOut(transition_duration); maxText.FadeOut(transition_duration); @@ -71,7 +67,7 @@ namespace osu.Game.Screens.Multi.Components else { slash.FadeIn(transition_duration); - maxText.Text = Max.ToString(); + maxText.Text = MaxParticipants.Value.ToString(); maxText.FadeIn(transition_duration); } } diff --git a/osu.Game/Screens/Multi/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Components/ParticipantInfo.cs index b1c77a04af..47aff3f200 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantInfo.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -16,36 +17,21 @@ namespace osu.Game.Screens.Multi.Components { public class ParticipantInfo : Container { - private readonly Container flagContainer; private readonly OsuSpriteText host; private readonly FillFlowContainer levelRangeContainer; - private readonly OsuSpriteText levelRangeLower; - private readonly OsuSpriteText levelRangeHigher; - public User Host - { - set - { - host.Text = value.Username; - flagContainer.Children = new[] { new DrawableFlag(value.Country) { RelativeSizeAxes = Axes.Both } }; - } - } - - public IEnumerable Participants - { - set - { - var ranks = value.Select(u => u.Statistics.Ranks.Global); - levelRangeLower.Text = ranks.Min().ToString(); - levelRangeHigher.Text = ranks.Max().ToString(); - } - } + public readonly Bindable Host = new Bindable(); + public readonly Bindable> Participants = new Bindable>(); public ParticipantInfo(string rankPrefix = null) { RelativeSizeAxes = Axes.X; Height = 15f; + OsuSpriteText levelRangeHigher; + OsuSpriteText levelRangeLower; + Container flagContainer; + Children = new Drawable[] { new FillFlowContainer @@ -133,6 +119,19 @@ namespace osu.Game.Screens.Multi.Components }, }, }; + + Host.BindValueChanged(v => + { + host.Text = v.Username; + flagContainer.Child = new DrawableFlag(v.Country) { RelativeSizeAxes = Axes.Both }; + }); + + Participants.BindValueChanged(v => + { + var ranks = v.Select(u => u.Statistics.Ranks.Global); + levelRangeLower.Text = ranks.Min().ToString(); + levelRangeHigher.Text = ranks.Max().ToString(); + }); } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs index b7dcb3c8fb..d282264ed6 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -29,10 +29,10 @@ namespace osu.Game.Screens.Multi.Components private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; private readonly Bindable nameBind = new Bindable(); + private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable hostBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); - private readonly Bindable roomBeatmap = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Multi.Components hostBind.UnbindBindings(); statusBind.UnbindBindings(); typeBind.UnbindBindings(); - roomBeatmap.UnbindBindings(); + beatmapBind.UnbindBindings(); maxParticipantsBind.UnbindBindings(); participantsBind.UnbindBindings(); @@ -74,7 +74,7 @@ namespace osu.Game.Screens.Multi.Components hostBind.BindTo(room.Host); statusBind.BindTo(room.Status); typeBind.BindTo(room.Type); - roomBeatmap.BindTo(room.Beatmap); + beatmapBind.BindTo(room.Beatmap); maxParticipantsBind.BindTo(room.MaxParticipants); participantsBind.BindTo(room.Participants); } @@ -131,6 +131,7 @@ namespace osu.Game.Screens.Multi.Components Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, TextSize = 30, + Current = nameBind }, }, }, @@ -203,26 +204,20 @@ namespace osu.Game.Screens.Multi.Components }, }; - nameBind.ValueChanged += n => name.Text = n; - hostBind.ValueChanged += h => participantInfo.Host = h; - typeBind.ValueChanged += t => beatmapTypeInfo.Type = t; - maxParticipantsBind.ValueChanged += m => participantCount.Max = m; statusBind.ValueChanged += displayStatus; + beatmapBind.ValueChanged += b => beatmap.Value = beatmaps.GetWorkingBeatmap(b); + participantsBind.ValueChanged += p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u)); background.Beatmap.BindTo(beatmap); - roomBeatmap.ValueChanged += b => - { - beatmap.Value = beatmaps.GetWorkingBeatmap(b); - beatmapTypeInfo.Beatmap = b; - }; + participantInfo.Host.BindTo(hostBind); + participantInfo.Participants.BindTo(participantsBind); - participantsBind.ValueChanged += p => - { - participantCount.Count = p.Count(); - participantInfo.Participants = p; - participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u)); - }; + participantCount.Participants.BindTo(participantsBind); + participantCount.MaxParticipants.BindTo(maxParticipantsBind); + + beatmapTypeInfo.Type.BindTo(typeBind); + beatmapTypeInfo.Beatmap.BindTo(beatmapBind); updateState(); } @@ -265,7 +260,7 @@ namespace osu.Game.Screens.Multi.Components participantInfo.FadeIn(transition_duration); statusBind.TriggerChange(); - roomBeatmap.TriggerChange(); + beatmapBind.TriggerChange(); } } diff --git a/osu.Game/Screens/Multi/Screens/Match/Info.cs b/osu.Game/Screens/Multi/Screens/Match/Info.cs index fc6e84c38a..9600a878a6 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Info.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Info.cs @@ -99,10 +99,11 @@ namespace osu.Game.Screens.Multi.Screens.Match }, }; + beatmapTypeInfo.Beatmap.BindTo(Beatmap); + beatmapTypeInfo.Type.BindTo(Type); + Availability.BindValueChanged(_ => updateAvailabilityStatus()); Status.BindValueChanged(_ => updateAvailabilityStatus()); - Beatmap.BindValueChanged(b => beatmapTypeInfo.Beatmap = b); - Type.BindValueChanged(t => beatmapTypeInfo.Type = t); } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Screens/Match/Participants.cs b/osu.Game/Screens/Multi/Screens/Match/Participants.cs index d40796760b..98ab758f81 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Participants.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Participants.cs @@ -60,6 +60,9 @@ namespace osu.Game.Screens.Multi.Screens.Match }, }; + count.Participants.BindTo(Users); + count.MaxParticipants.BindTo(MaxParticipants); + Users.BindValueChanged(v => { usersFlow.Children = v.Select(u => new UserPanel(u) @@ -69,11 +72,7 @@ namespace osu.Game.Screens.Multi.Screens.Match Width = 300, OnLoadComplete = d => d.FadeInFromZero(60), }).ToList(); - - count.Count = v.Count(); }); - - MaxParticipants.BindValueChanged(v => count.Max = v); } } } From 2d0fdc820440e03cbc61dedf6b629c9a72c7abc4 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Sun, 9 Dec 2018 17:39:35 +0300 Subject: [PATCH 024/220] Create ReplayPlayer using Score from the dummy RulesetContainer --- osu.Game.Tests/Visual/TestCaseReplay.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs index 2f217d013b..0fc4616f56 100644 --- a/osu.Game.Tests/Visual/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/TestCaseReplay.cs @@ -5,7 +5,6 @@ using System.ComponentModel; using System.Linq; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; -using osu.Game.Scoring; using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual @@ -23,7 +22,7 @@ namespace osu.Game.Tests.Visual // Reset the mods Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay)); - return new ReplayPlayer(new Score { Replay = dummyRulesetContainer.ReplayScore.Replay }); + return new ReplayPlayer(dummyRulesetContainer.ReplayScore); } } } From 352a758f5ce14f4c6cdf9198b6e6a79948538939 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 13:18:03 +0900 Subject: [PATCH 025/220] Replace 3 occurrences of SpriteText.Current --- osu.Game/Screens/Multi/Components/DrawableRoom.cs | 10 ++++------ osu.Game/Screens/Multi/Components/RoomInspector.cs | 9 +++++---- osu.Game/Screens/Multi/Screens/Match/Info.cs | 13 ++++--------- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Components/DrawableRoom.cs index 43a9b6ad06..9425457670 100644 --- a/osu.Game/Screens/Multi/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Components/DrawableRoom.cs @@ -108,6 +108,7 @@ namespace osu.Game.Screens.Multi.Components ParticipantInfo participantInfo; BeatmapTitle beatmapTitle; ModeTypeInfo modeTypeInfo; + OsuSpriteText name; Children = new Drawable[] { @@ -166,11 +167,7 @@ namespace osu.Game.Screens.Multi.Components Spacing = new Vector2(5f), Children = new Drawable[] { - new OsuSpriteText - { - TextSize = 18, - Current = nameBind - }, + name = new OsuSpriteText { TextSize = 18 }, participantInfo = new ParticipantInfo(), }, }, @@ -217,7 +214,8 @@ namespace osu.Game.Screens.Multi.Components background.Beatmap.BindTo(beatmap); - beatmapBind.ValueChanged += b => beatmap.Value = beatmaps.GetWorkingBeatmap(b); + beatmapBind.BindValueChanged(b => beatmap.Value = beatmaps.GetWorkingBeatmap(b)); + nameBind.BindValueChanged(n => name.Text = n); nameBind.BindTo(Room.Name); hostBind.BindTo(Room.Host); diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs index d282264ed6..48d1c1b93c 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -131,7 +131,6 @@ namespace osu.Game.Screens.Multi.Components Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, TextSize = 30, - Current = nameBind }, }, }, @@ -204,9 +203,11 @@ namespace osu.Game.Screens.Multi.Components }, }; - statusBind.ValueChanged += displayStatus; - beatmapBind.ValueChanged += b => beatmap.Value = beatmaps.GetWorkingBeatmap(b); - participantsBind.ValueChanged += p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u)); + statusBind.BindValueChanged(displayStatus); + beatmapBind.BindValueChanged(b => beatmap.Value = beatmaps.GetWorkingBeatmap(b)); + participantsBind.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u))); + + nameBind.BindValueChanged(n => name.Text = n); background.Beatmap.BindTo(beatmap); diff --git a/osu.Game/Screens/Multi/Screens/Match/Info.cs b/osu.Game/Screens/Multi/Screens/Match/Info.cs index 9600a878a6..d479765159 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Info.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Info.cs @@ -42,6 +42,7 @@ namespace osu.Game.Screens.Multi.Screens.Match Height = HEIGHT; BeatmapTypeInfo beatmapTypeInfo; + OsuSpriteText name; Children = new Drawable[] { @@ -69,15 +70,8 @@ namespace osu.Game.Screens.Multi.Screens.Match Direction = FillDirection.Vertical, Children = new Drawable[] { - new OsuSpriteText - { - TextSize = 30, - Current = Name - }, - availabilityStatus = new OsuSpriteText - { - TextSize = 14, - }, + name = new OsuSpriteText { TextSize = 30 }, + availabilityStatus = new OsuSpriteText { TextSize = 14 }, }, }, beatmapTypeInfo = new BeatmapTypeInfo @@ -104,6 +98,7 @@ namespace osu.Game.Screens.Multi.Screens.Match Availability.BindValueChanged(_ => updateAvailabilityStatus()); Status.BindValueChanged(_ => updateAvailabilityStatus()); + Name.BindValueChanged(n => name.Text = n); } [BackgroundDependencyLoader] From 41c7d10dff8edad5407d64689d6c5b678b3e93e1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 13:48:05 +0900 Subject: [PATCH 026/220] Fix compilation issues (+ use updated framework) --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 2 +- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Overlays/Music/PlaylistItem.cs | 3 ++- osu.Game/osu.Game.csproj | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 54a2ea47f9..795fe7caf4 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -62,7 +62,7 @@ namespace osu.Game.Graphics.Containers public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action creationParameters = null) { - AddInternal(new DrawableLinkCompiler(AddText(text, creationParameters).ToList()) + AddInternal(new DrawableLinkCompiler(AddText(text, creationParameters).OfType().ToList()) { TooltipText = tooltipText ?? (url != text ? url : string.Empty), Action = () => diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index cd40d4793a..73ecbafb9e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -553,9 +553,9 @@ namespace osu.Game try { - Logger.Log($"Loading {d}...", LoggingTarget.Debug); + Logger.Log($"Loading {d}...", level: LogLevel.Debug); await LoadComponentAsync(d, add); - Logger.Log($"Loaded {d}!", LoggingTarget.Debug); + Logger.Log($"Loaded {d}!", level: LogLevel.Debug); } catch (OperationCanceledException) { diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 5d89e53081..2f5bcd129a 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -111,7 +112,7 @@ namespace osu.Game.Overlays.Music { sprite.TextSize = 16; sprite.Font = @"Exo2.0-Regular"; - }); + }).OfType(); text.AddText(artistBind.Value, sprite => { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a1578b6eb8..cdb94d6ab7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From be3a912d0be20e372a7d01c52cb57168ed0f4c5e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 13:48:10 +0900 Subject: [PATCH 027/220] Use UnbindFrom() --- .../Screens/Multi/Components/RoomInspector.cs | 25 +++++++++++-------- .../Multi/Components/RoomSettingsOverlay.cs | 13 ++++++---- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs index 48d1c1b93c..07cf5541c5 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -54,19 +54,24 @@ namespace osu.Game.Screens.Multi.Components private Room room; public Room Room { - get { return room; } + get => room; set { - if (value == room) return; - room = value; + if (value == room) + return; - nameBind.UnbindBindings(); - hostBind.UnbindBindings(); - statusBind.UnbindBindings(); - typeBind.UnbindBindings(); - beatmapBind.UnbindBindings(); - maxParticipantsBind.UnbindBindings(); - participantsBind.UnbindBindings(); + if (room != null) + { + nameBind.UnbindFrom(room.Name); + hostBind.UnbindFrom(room.Host); + statusBind.UnbindFrom(room.Status); + typeBind.UnbindFrom(room.Type); + beatmapBind.UnbindFrom(room.Beatmap); + maxParticipantsBind.UnbindFrom(room.MaxParticipants); + participantsBind.UnbindFrom(room.Participants); + } + + room = value; if (room != null) { diff --git a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs index bd9b269452..92a8fc8bb7 100644 --- a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs @@ -190,12 +190,15 @@ namespace osu.Game.Screens.Multi.Components if (room == value) return; - room = value; + if (room != null) + { + nameBind.UnbindFrom(room.Name); + availabilityBind.UnbindFrom(room.Availability); + typeBind.UnbindFrom(room.Type); + maxParticipantsBind.UnbindFrom(room.MaxParticipants); + } - nameBind.UnbindBindings(); - availabilityBind.UnbindBindings(); - typeBind.UnbindBindings(); - maxParticipantsBind.UnbindBindings(); + room = value; if (room != null) { From c7970e54253415692b1a474da96f483abbec1aae Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 16:50:00 +0900 Subject: [PATCH 028/220] Cleanup handling of readonly fields --- .../Multi/Components/DisableableTabControl.cs | 26 +++++------ .../Multi/Components/RoomSettingsOverlay.cs | 44 ++++++++++--------- .../Lounge}/CreateRoomOverlay.cs | 11 ++++- osu.Game/Screens/Multi/Screens/Match/Match.cs | 3 +- 4 files changed, 49 insertions(+), 35 deletions(-) rename osu.Game/Screens/Multi/{Components => Screens/Lounge}/CreateRoomOverlay.cs (69%) diff --git a/osu.Game/Screens/Multi/Components/DisableableTabControl.cs b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs index 1ca61a2678..e2a44f7ff4 100644 --- a/osu.Game/Screens/Multi/Components/DisableableTabControl.cs +++ b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; +using osu.Framework.Configuration; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; @@ -9,33 +9,33 @@ namespace osu.Game.Screens.Multi.Components { public abstract class DisableableTabControl : TabControl { - public IEnumerable DisabledItems + public readonly BindableBool ReadOnly = new BindableBool(); + + protected override void AddTabItem(TabItem tab, bool addToDropdown = true) { - set - { - foreach (var item in value) - (TabMap[item] as DisableableTabItem)?.Disable(); - } + if (tab is DisableableTabItem disableable) + disableable.ReadOnly.BindTo(ReadOnly); + base.AddTabItem(tab, addToDropdown); } protected abstract class DisableableTabItem : TabItem { + public readonly BindableBool ReadOnly = new BindableBool(); + protected DisableableTabItem(T value) : base(value) { + ReadOnly.BindValueChanged(updateReadOnly); } - private bool isDisabled; - - public void Disable() + private void updateReadOnly(bool readOnly) { - Alpha = 0.2f; - isDisabled = true; + Alpha = readOnly ? 0.2f : 1; } protected override bool OnClick(ClickEvent e) { - if (isDisabled) + if (ReadOnly) return true; return base.OnClick(e); } diff --git a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs index 92a8fc8bb7..4e0a9ff3a2 100644 --- a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs @@ -40,6 +40,7 @@ namespace osu.Game.Screens.Multi.Components protected readonly RoomAvailabilityPicker AvailabilityPicker; protected readonly GameTypePicker TypePicker; protected readonly TriangleButton ApplyButton; + protected readonly OsuPasswordTextBox PasswordField; public RoomSettingsOverlay() { @@ -116,20 +117,16 @@ namespace osu.Game.Screens.Multi.Components { RelativeSizeAxes = Axes.X, TabbableContentContainer = this, - Alpha = 0.2f, - ReadOnly = true, OnCommit = (sender, text) => apply(), }, }, new Section("PASSWORD (OPTIONAL)") { - Child = new SettingsPasswordTextBox + Child = PasswordField = new SettingsPasswordTextBox { RelativeSizeAxes = Axes.X, TabbableContentContainer = this, - OnCommit = (sender, text) => apply(), - Alpha = 0.2f, - ReadOnly = true, + OnCommit = (sender, text) => apply() }, }, }, @@ -154,20 +151,6 @@ namespace osu.Game.Screens.Multi.Components typeBind.ValueChanged += t => TypePicker.Current.Value = t; maxParticipantsBind.ValueChanged += m => MaxParticipantsField.Text = m?.ToString(); - AvailabilityPicker.DisabledItems = new[] - { - RoomAvailability.FriendsOnly, - RoomAvailability.InviteOnly - }; - - TypePicker.DisabledItems = new GameType[] - { - new GameTypeTag(), - new GameTypeVersus(), - new GameTypeTagTeam(), - new GameTypeTeamVersus(), - }; - Room = new Room(); } @@ -177,6 +160,27 @@ namespace osu.Game.Screens.Multi.Components typeLabel.Colour = colours.Yellow; } + private bool readOnly; + + public bool ReadOnly + { + get => readOnly; + set + { + if (readOnly == value) + return; + readOnly = value; + + NameField.ReadOnly = value; + MaxParticipantsField.ReadOnly = value; + PasswordField.ReadOnly = value; + AvailabilityPicker.ReadOnly.Value = value; + TypePicker.ReadOnly.Value = value; + ApplyButton.Enabled.Value = !value; + } + } + + private Room room; /// diff --git a/osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs b/osu.Game/Screens/Multi/Screens/Lounge/CreateRoomOverlay.cs similarity index 69% rename from osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs rename to osu.Game/Screens/Multi/Screens/Lounge/CreateRoomOverlay.cs index 3a6224da26..45acb7ebec 100644 --- a/osu.Game/Screens/Multi/Components/CreateRoomOverlay.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/CreateRoomOverlay.cs @@ -4,14 +4,23 @@ using osu.Framework.Allocation; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Components; -namespace osu.Game.Screens.Multi.Components +namespace osu.Game.Screens.Multi.Screens.Lounge { public class CreateRoomOverlay : RoomSettingsOverlay { [Resolved] private APIAccess api { get; set; } + public CreateRoomOverlay() + { + MaxParticipantsField.ReadOnly = true; + AvailabilityPicker.ReadOnly.Value = true; + TypePicker.ReadOnly.Value = true; + PasswordField.ReadOnly = true; + } + [BackgroundDependencyLoader] private void load() { diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs index 4f81ffd305..74e5bf0a85 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -75,7 +75,8 @@ namespace osu.Game.Screens.Multi.Screens.Match { RelativeSizeAxes = Axes.Both, Height = 0.9f, - Room = room + Room = room, + ReadOnly = true }, }, }; From 3b688c702c5cfd82b4c1e0a5b968d0aac844113e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 17:06:34 +0900 Subject: [PATCH 029/220] Use graying rather than alpha --- osu.Game/Screens/Multi/Components/DisableableTabControl.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Components/DisableableTabControl.cs b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs index e2a44f7ff4..fdc2fd578d 100644 --- a/osu.Game/Screens/Multi/Components/DisableableTabControl.cs +++ b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs @@ -4,6 +4,7 @@ using osu.Framework.Configuration; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; +using osuTK.Graphics; namespace osu.Game.Screens.Multi.Components { @@ -30,7 +31,7 @@ namespace osu.Game.Screens.Multi.Components private void updateReadOnly(bool readOnly) { - Alpha = readOnly ? 0.2f : 1; + Colour = readOnly ? Color4.Gray : Color4.White; } protected override bool OnClick(ClickEvent e) From 77193eeea4b925caee2e0bd96d347222f655f1df Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 18:00:57 +0900 Subject: [PATCH 030/220] Move from lobby into match for creation process --- osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 1 + osu.Game/Online/Multiplayer/Room.cs | 2 + .../Multi/Screens/Lounge/CreateRoomOverlay.cs | 42 ------------ .../Screens/Multi/Screens/Lounge/Lounge.cs | 22 ++---- .../Screens/Multi/Screens/Match/Header.cs | 7 +- osu.Game/Screens/Multi/Screens/Match/Match.cs | 16 +++-- .../Screens/Multi/Screens/Match/MatchPage.cs | 28 ++++++++ .../Multi/Screens/Match/MatchTabControl.cs | 68 +++++++++++++++++++ .../Match}/RoomSettingsOverlay.cs | 3 +- 9 files changed, 119 insertions(+), 70 deletions(-) delete mode 100644 osu.Game/Screens/Multi/Screens/Lounge/CreateRoomOverlay.cs create mode 100644 osu.Game/Screens/Multi/Screens/Match/MatchPage.cs create mode 100644 osu.Game/Screens/Multi/Screens/Match/MatchTabControl.cs rename osu.Game/Screens/Multi/{Components => Screens/Match}/RoomSettingsOverlay.cs (99%) diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index 463002fbcb..b0b287fdb3 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Testing.Input; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Components; +using osu.Game.Screens.Multi.Screens.Match; using osuTK.Input; namespace osu.Game.Tests.Visual diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 8395b7e638..67ddb60823 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -19,5 +19,7 @@ namespace osu.Game.Online.Multiplayer public Bindable Beatmap = new Bindable(); public Bindable MaxParticipants = new Bindable(); public Bindable> Participants = new Bindable>(Enumerable.Empty()); + + public Bindable Created = new Bindable(); } } diff --git a/osu.Game/Screens/Multi/Screens/Lounge/CreateRoomOverlay.cs b/osu.Game/Screens/Multi/Screens/Lounge/CreateRoomOverlay.cs deleted file mode 100644 index 45acb7ebec..0000000000 --- a/osu.Game/Screens/Multi/Screens/Lounge/CreateRoomOverlay.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Game.Online.API; -using osu.Game.Online.Multiplayer; -using osu.Game.Screens.Multi.Components; - -namespace osu.Game.Screens.Multi.Screens.Lounge -{ - public class CreateRoomOverlay : RoomSettingsOverlay - { - [Resolved] - private APIAccess api { get; set; } - - public CreateRoomOverlay() - { - MaxParticipantsField.ReadOnly = true; - AvailabilityPicker.ReadOnly.Value = true; - TypePicker.ReadOnly.Value = true; - PasswordField.ReadOnly = true; - } - - [BackgroundDependencyLoader] - private void load() - { - Room.Host.Value = api.LocalUser; - } - - public override Room Room - { - get => base.Room; - set - { - base.Room = value; - - if (api != null && value != null) - value.Host.Value = api.LocalUser; - } - } - } -} diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index 140b3550c1..6fa254be05 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -19,7 +19,6 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { private readonly Container content; private readonly SearchContainer search; - private readonly CreateRoomOverlay createRoomOverlay; protected readonly FilterControl Filter; protected readonly FillFlowContainer RoomsContainer; @@ -68,16 +67,6 @@ namespace osu.Game.Screens.Multi.Screens.Lounge RelativeSizeAxes = Axes.Both, Width = 0.45f, }, - new Container - { - RelativeSizeAxes = Axes.Both, - Child = createRoomOverlay = new CreateRoomOverlay - { - RelativeSizeAxes = Axes.Both, - Height = 0.9f, - Room = new Room() - }, - }, }, } }; @@ -85,8 +74,6 @@ namespace osu.Game.Screens.Multi.Screens.Lounge Filter.Search.Current.ValueChanged += s => filterRooms(); Filter.Tabs.Current.ValueChanged += t => filterRooms(); Filter.Search.Exit += Exit; - - createRoomOverlay.Applied = () => createRoom(createRoomOverlay.Room); } protected override void UpdateAfterChildren() @@ -147,8 +134,6 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { base.OnResuming(last); - createRoomOverlay.Room = new Room(); - Filter.Search.HoldFocus = true; } @@ -161,9 +146,10 @@ namespace osu.Game.Screens.Multi.Screens.Lounge private void filterRooms() { if (Filter.Tabs.Current.Value == LoungeTab.Create) - createRoomOverlay.Show(); - else - createRoomOverlay.Hide(); + { + Filter.Tabs.Current.Value = LoungeTab.Public; + createRoom(new Room()); + } search.SearchTerm = Filter.Search.Current.Value ?? string.Empty; diff --git a/osu.Game/Screens/Multi/Screens/Match/Header.cs b/osu.Game/Screens/Multi/Screens/Match/Header.cs index 50db63e3e3..78a4a937a4 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Header.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Header.cs @@ -15,7 +15,6 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.SearchableList; using osuTK.Graphics; @@ -29,7 +28,7 @@ namespace osu.Game.Screens.Multi.Screens.Match private readonly Box tabStrip; - public readonly PageTabControl Tabs; + public readonly MatchTabControl Tabs; public Action OnRequestSelectBeatmap; @@ -78,11 +77,11 @@ namespace osu.Game.Screens.Multi.Screens.Match RelativeSizeAxes = Axes.Both, }, }, - Tabs = new PageTabControl + Tabs = new MatchTabControl { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, + RelativeSizeAxes = Axes.X }, }, }, diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs index 74e5bf0a85..f444cb4073 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -7,8 +7,8 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Online.API; using osu.Game.Online.Multiplayer; -using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Select; using osu.Game.Users; @@ -16,7 +16,6 @@ namespace osu.Game.Screens.Multi.Screens.Match { public class Match : MultiplayerScreen { - private readonly Room room; private readonly Participants participants; private readonly Bindable nameBind = new Bindable(); @@ -33,9 +32,17 @@ namespace osu.Game.Screens.Multi.Screens.Match public override string ShortTitle => "room"; + private readonly Header header; + + [Cached] + private readonly Room room; + [Resolved] private BeatmapManager beatmapManager { get; set; } + [Resolved] + private APIAccess api { get; set; } + public Match(Room room) { this.room = room; @@ -48,7 +55,6 @@ namespace osu.Game.Screens.Multi.Screens.Match participantsBind.BindTo(room.Participants); maxParticipantsBind.BindTo(room.MaxParticipants); - Header header; RoomSettingsOverlay settings; Info info; @@ -86,7 +92,7 @@ namespace osu.Game.Screens.Multi.Screens.Match header.Tabs.Current.ValueChanged += t => { - if (t == MatchHeaderPage.Settings) + if (t is SettingsMatchPage) settings.Show(); else settings.Hide(); @@ -95,7 +101,7 @@ namespace osu.Game.Screens.Multi.Screens.Match settings.StateChanged += s => { if (s == Visibility.Hidden) - header.Tabs.Current.Value = MatchHeaderPage.Room; + header.Tabs.Current.Value = new RoomMatchPage(); }; settings.Applied = () => settings.Hide(); diff --git a/osu.Game/Screens/Multi/Screens/Match/MatchPage.cs b/osu.Game/Screens/Multi/Screens/Match/MatchPage.cs new file mode 100644 index 0000000000..710e41ec69 --- /dev/null +++ b/osu.Game/Screens/Multi/Screens/Match/MatchPage.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; + +namespace osu.Game.Screens.Multi.Screens.Match +{ + public abstract class MatchPage + { + public abstract string Name { get; } + + public readonly BindableBool Enabled = new BindableBool(true); + + public override string ToString() => Name; + public override int GetHashCode() => GetType().GetHashCode(); + public override bool Equals(object obj) => GetType() == obj?.GetType(); + } + + public class SettingsMatchPage : MatchPage + { + public override string Name => "Settings"; + } + + public class RoomMatchPage : MatchPage + { + public override string Name => "Room"; + } +} diff --git a/osu.Game/Screens/Multi/Screens/Match/MatchTabControl.cs b/osu.Game/Screens/Multi/Screens/Match/MatchTabControl.cs new file mode 100644 index 0000000000..5fd64179cd --- /dev/null +++ b/osu.Game/Screens/Multi/Screens/Match/MatchTabControl.cs @@ -0,0 +1,68 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Multiplayer; +using osuTK.Graphics; + +namespace osu.Game.Screens.Multi.Screens.Match +{ + public class MatchTabControl : PageTabControl + { + private readonly IBindable created = new Bindable(); + + [Resolved] + private Room room { get; set; } + + public MatchTabControl() + { + AddItem(new SettingsMatchPage()); + AddItem(new RoomMatchPage()); + } + + [BackgroundDependencyLoader] + private void load() + { + created.BindTo(room.Created); + created.BindValueChanged(v => + { + if (v) + { + Items.ForEach(t => t.Enabled.Value = !(t is SettingsMatchPage)); + Current.Value = new RoomMatchPage(); + } + else + { + Items.ForEach(t => t.Enabled.Value = t is SettingsMatchPage); + Current.Value = new SettingsMatchPage(); + } + }, true); + } + + protected override TabItem CreateTabItem(MatchPage value) => new TabItem(value); + + private class TabItem : PageTabItem + { + private readonly IBindable enabled = new BindableBool(); + + public TabItem(MatchPage value) + : base(value) + { + enabled.BindTo(value.Enabled); + enabled.BindValueChanged(v => Colour = v ? Color4.White : Color4.Gray); + } + + protected override bool OnClick(ClickEvent e) + { + if (!enabled.Value) + return true; + return base.OnClick(e); + } + } + } +} diff --git a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs similarity index 99% rename from osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs rename to osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs index 4e0a9ff3a2..7fba56b2d3 100644 --- a/osu.Game/Screens/Multi/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs @@ -12,10 +12,11 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; +using osu.Game.Screens.Multi.Components; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Components +namespace osu.Game.Screens.Multi.Screens.Match { public class RoomSettingsOverlay : FocusedOverlayContainer { From ca544ef3fec321d67763ace251588af1fafee26a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 18:25:32 +0900 Subject: [PATCH 031/220] Adjust match creation process --- osu.Game/Screens/Multi/Screens/Match/Match.cs | 13 +-- .../Screens/Match/RoomSettingsOverlay.cs | 83 ++++++------------- 2 files changed, 26 insertions(+), 70 deletions(-) diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs index f444cb4073..40590a6982 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -32,8 +32,6 @@ namespace osu.Game.Screens.Multi.Screens.Match public override string ShortTitle => "room"; - private readonly Header header; - [Cached] private readonly Room room; @@ -55,6 +53,7 @@ namespace osu.Game.Screens.Multi.Screens.Match participantsBind.BindTo(room.Participants); maxParticipantsBind.BindTo(room.MaxParticipants); + Header header; RoomSettingsOverlay settings; Info info; @@ -81,8 +80,6 @@ namespace osu.Game.Screens.Multi.Screens.Match { RelativeSizeAxes = Axes.Both, Height = 0.9f, - Room = room, - ReadOnly = true }, }, }; @@ -98,14 +95,6 @@ namespace osu.Game.Screens.Multi.Screens.Match settings.Hide(); }; - settings.StateChanged += s => - { - if (s == Visibility.Hidden) - header.Tabs.Current.Value = new RoomMatchPage(); - }; - - settings.Applied = () => settings.Hide(); - info.Beatmap.BindTo(beatmapBind); info.Name.BindTo(nameBind); info.Status.BindTo(statusBind); diff --git a/osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs index 7fba56b2d3..747c109e3f 100644 --- a/osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs @@ -1,12 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -23,15 +23,12 @@ namespace osu.Game.Screens.Multi.Screens.Match private const float transition_duration = 350; private const float field_padding = 45; - /// - /// Invoked when room settings were applied. - /// - public Action Applied; - private readonly Bindable nameBind = new Bindable(); + private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable availabilityBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); + private readonly Bindable createdBind = new Bindable(); private readonly Container content; @@ -43,6 +40,9 @@ namespace osu.Game.Screens.Multi.Screens.Match protected readonly TriangleButton ApplyButton; protected readonly OsuPasswordTextBox PasswordField; + [Resolved] + private Room room { get; set; } + public RoomSettingsOverlay() { Masking = true; @@ -151,69 +151,35 @@ namespace osu.Game.Screens.Multi.Screens.Match availabilityBind.ValueChanged += a => AvailabilityPicker.Current.Value = a; typeBind.ValueChanged += t => TypePicker.Current.Value = t; maxParticipantsBind.ValueChanged += m => MaxParticipantsField.Text = m?.ToString(); - - Room = new Room(); } [BackgroundDependencyLoader] private void load(OsuColour colours) { typeLabel.Colour = colours.Yellow; + + nameBind.BindTo(room.Name); + beatmapBind.BindTo(room.Beatmap); + availabilityBind.BindTo(room.Availability); + typeBind.BindTo(room.Type); + maxParticipantsBind.BindTo(room.MaxParticipants); + createdBind.BindTo(room.Created); + + MaxParticipantsField.ReadOnly = true; + PasswordField.ReadOnly = true; + AvailabilityPicker.ReadOnly.Value = true; + TypePicker.ReadOnly.Value = true; + ApplyButton.Enabled.Value = false; } - private bool readOnly; - - public bool ReadOnly + protected override void Update() { - get => readOnly; - set - { - if (readOnly == value) - return; - readOnly = value; + base.Update(); - NameField.ReadOnly = value; - MaxParticipantsField.ReadOnly = value; - PasswordField.ReadOnly = value; - AvailabilityPicker.ReadOnly.Value = value; - TypePicker.ReadOnly.Value = value; - ApplyButton.Enabled.Value = !value; - } + ApplyButton.Enabled.Value = hasValidSettings; } - - private Room room; - - /// - /// The room which settings are being applied to. - /// - public virtual Room Room - { - get => room; - set - { - if (room == value) - return; - - if (room != null) - { - nameBind.UnbindFrom(room.Name); - availabilityBind.UnbindFrom(room.Availability); - typeBind.UnbindFrom(room.Type); - maxParticipantsBind.UnbindFrom(room.MaxParticipants); - } - - room = value; - - if (room != null) - { - nameBind.BindTo(room.Name); - availabilityBind.BindTo(room.Availability); - typeBind.BindTo(room.Type); - maxParticipantsBind.BindTo(room.MaxParticipants); - } - } - } + private bool hasValidSettings => NameField.Text.Length > 0 && beatmapBind.Value != null; protected override void PopIn() { @@ -245,7 +211,8 @@ namespace osu.Game.Screens.Multi.Screens.Match else maxParticipantsBind.Value = null; - Applied?.Invoke(); + // Todo: This should only be set after the room has been created server-side + createdBind.Value = true; } private class SettingsTextBox : OsuTextBox From 3f64cfc1c68144beb5065cc7096323771927cb4f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 18:35:08 +0900 Subject: [PATCH 032/220] Don't add rooms to lounge until they're actually created --- .../Screens/Multi/Screens/Lounge/Lounge.cs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index 6fa254be05..19205065bc 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Framework.Configuration; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -26,6 +27,9 @@ namespace osu.Game.Screens.Multi.Screens.Lounge public override string Title => "Lounge"; + private Room roomBeingCreated; + private readonly IBindable roomCreated = new Bindable(); + protected override Drawable TransitionContent => content; public Lounge() @@ -74,6 +78,12 @@ namespace osu.Game.Screens.Multi.Screens.Lounge Filter.Search.Current.ValueChanged += s => filterRooms(); Filter.Tabs.Current.ValueChanged += t => filterRooms(); Filter.Search.Exit += Exit; + + roomCreated.BindValueChanged(v => + { + if (v) + addRoom(roomBeingCreated); + }); } protected override void UpdateAfterChildren() @@ -147,8 +157,14 @@ namespace osu.Game.Screens.Multi.Screens.Lounge { if (Filter.Tabs.Current.Value == LoungeTab.Create) { + roomBeingCreated = new Room(); + + roomCreated.UnbindBindings(); + roomCreated.BindTo(roomBeingCreated.Created); + Filter.Tabs.Current.Value = LoungeTab.Public; - createRoom(new Room()); + + Push(new Match.Match(roomBeingCreated)); } search.SearchTerm = Filter.Search.Current.Value ?? string.Empty; @@ -181,12 +197,6 @@ namespace osu.Game.Screens.Multi.Screens.Lounge Push(new Match.Match(room.Room)); } - private void createRoom(Room room) - { - openRoom(addRoom(room)); - Filter.Tabs.Current.Value = LoungeTab.Public; - } - private class RoomsFilterContainer : FillFlowContainer, IHasFilterableChildren { public IEnumerable FilterTerms => new string[] { }; From 3c44f9e4f132337e6f0b79b13c2cb85f8b699cd9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 18:50:52 +0900 Subject: [PATCH 033/220] Make select beatmap button into a triangle button --- .../Screens/Multi/Screens/Match/Header.cs | 78 +------------------ 1 file changed, 4 insertions(+), 74 deletions(-) diff --git a/osu.Game/Screens/Multi/Screens/Match/Header.cs b/osu.Game/Screens/Multi/Screens/Match/Header.cs index 78a4a937a4..c06201a334 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Header.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Header.cs @@ -9,12 +9,10 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.SearchableList; using osuTK.Graphics; @@ -75,6 +73,7 @@ namespace osu.Game.Screens.Multi.Screens.Match Child = beatmapButton = new BeatmapSelectButton { RelativeSizeAxes = Axes.Both, + Height = 1 }, }, Tabs = new MatchTabControl @@ -98,80 +97,11 @@ namespace osu.Game.Screens.Multi.Screens.Match tabStrip.Colour = colours.Yellow; } - private class BeatmapSelectButton : OsuClickableContainer + private class BeatmapSelectButton : TriangleButton { - private const float corner_radius = 5; - private const float bg_opacity = 0.5f; - private const float transition_duration = 100; - - private readonly Box bg; - private readonly Container border; - public BeatmapSelectButton() { - Masking = true; - CornerRadius = corner_radius; - - Children = new Drawable[] - { - bg = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = bg_opacity, - }, - new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = @"Exo2.0-Bold", - Text = "Select Beatmap", - }, - border = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - CornerRadius = corner_radius, - BorderThickness = 4, - Alpha = 0, - Child = new Box // needs a child to show the border - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true - }, - }, - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - border.BorderColour = colours.Yellow; - } - - protected override bool OnHover(HoverEvent e) - { - border.FadeIn(transition_duration); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - base.OnHoverLost(e); - border.FadeOut(transition_duration); - } - - protected override bool OnMouseDown(MouseDownEvent e) - { - bg.FadeTo(0.75f, 1000, Easing.Out); - return base.OnMouseDown(e); - } - - protected override bool OnMouseUp(MouseUpEvent e) - { - bg.FadeTo(bg_opacity, transition_duration); - return base.OnMouseUp(e); + Text = "Select beatmap"; } } From cd41c456863aa1e74eafb70dd604c3735646d5df Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 19:03:22 +0900 Subject: [PATCH 034/220] Disable select beatmap button after room is created --- .../Screens/Multi/Screens/Match/Header.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Multi/Screens/Match/Header.cs b/osu.Game/Screens/Multi/Screens/Match/Header.cs index c06201a334..7d3525370f 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Header.cs +++ b/osu.Game/Screens/Multi/Screens/Match/Header.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; using osuTK.Graphics; @@ -99,10 +100,22 @@ namespace osu.Game.Screens.Multi.Screens.Match private class BeatmapSelectButton : TriangleButton { + private readonly IBindable createdBind = new Bindable(); + + [Resolved] + private Room room { get; set; } + public BeatmapSelectButton() { Text = "Select beatmap"; } + + [BackgroundDependencyLoader] + private void load() + { + createdBind.BindTo(room.Created); + createdBind.BindValueChanged(v => Enabled.Value = !v, true); + } } private class HeaderBeatmapBackgroundSprite : UpdateableBeatmapBackgroundSprite @@ -110,10 +123,4 @@ namespace osu.Game.Screens.Multi.Screens.Match protected override double FadeDuration => 0; } } - - public enum MatchHeaderPage - { - Settings, - Room, - } } From 1ac615b4905581b50c48e45c22f027a43ddb2a81 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Dec 2018 19:20:41 +0900 Subject: [PATCH 035/220] Renamespace --- osu.Game.Tests/Visual/TestCaseDrawableRoom.cs | 2 +- osu.Game.Tests/Visual/TestCaseLounge.cs | 40 +++++++++---------- osu.Game.Tests/Visual/TestCaseMatch.cs | 10 ++--- osu.Game.Tests/Visual/TestCaseMatchInfo.cs | 2 +- .../Visual/TestCaseMatchParticipants.cs | 2 +- osu.Game.Tests/Visual/TestCaseMultiHeader.cs | 8 ++-- osu.Game.Tests/Visual/TestCaseMultiScreen.cs | 5 ++- .../Visual/TestCaseRoomInspector.cs | 2 +- osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 3 +- osu.Game/Screens/Multi/Header.cs | 1 - .../Multi/{Screens => }/IMultiplayerScreen.cs | 2 +- .../{ => Lounge}/Components/DrawableRoom.cs | 3 +- .../Components}/FilterControl.cs | 2 +- .../Components/ParticipantInfo.cs | 2 +- .../{ => Lounge}/Components/RoomInspector.cs | 3 +- .../Lounge.cs => Lounge/LoungeScreen.cs} | 13 +++--- .../{ => Match}/Components/GameTypePicker.cs | 3 +- .../Match => Match/Components}/Header.cs | 2 +- .../Match => Match/Components}/Info.cs | 2 +- .../Match => Match/Components}/MatchPage.cs | 2 +- .../Components}/MatchTabControl.cs | 2 +- .../Components}/Participants.cs | 2 +- .../Components/RoomAvailabilityPicker.cs | 3 +- .../Components}/RoomSettingsOverlay.cs | 3 +- .../Match/Match.cs => Match/MatchScreen.cs} | 17 ++++---- osu.Game/Screens/Multi/Multiplayer.cs | 10 ++--- .../Multi/{Screens => }/MultiplayerScreen.cs | 2 +- osu.Game/Screens/Select/MatchSongSelect.cs | 2 +- 28 files changed, 77 insertions(+), 73 deletions(-) rename osu.Game/Screens/Multi/{Screens => }/IMultiplayerScreen.cs (85%) rename osu.Game/Screens/Multi/{ => Lounge}/Components/DrawableRoom.cs (99%) rename osu.Game/Screens/Multi/{Screens/Lounge => Lounge/Components}/FilterControl.cs (95%) rename osu.Game/Screens/Multi/{ => Lounge}/Components/ParticipantInfo.cs (99%) rename osu.Game/Screens/Multi/{ => Lounge}/Components/RoomInspector.cs (99%) rename osu.Game/Screens/Multi/{Screens/Lounge/Lounge.cs => Lounge/LoungeScreen.cs} (95%) rename osu.Game/Screens/Multi/{ => Match}/Components/GameTypePicker.cs (97%) rename osu.Game/Screens/Multi/{Screens/Match => Match/Components}/Header.cs (98%) rename osu.Game/Screens/Multi/{Screens/Match => Match/Components}/Info.cs (99%) rename osu.Game/Screens/Multi/{Screens/Match => Match/Components}/MatchPage.cs (93%) rename osu.Game/Screens/Multi/{Screens/Match => Match/Components}/MatchTabControl.cs (97%) rename osu.Game/Screens/Multi/{Screens/Match => Match/Components}/Participants.cs (98%) rename osu.Game/Screens/Multi/{ => Match}/Components/RoomAvailabilityPicker.cs (97%) rename osu.Game/Screens/Multi/{Screens/Match => Match/Components}/RoomSettingsOverlay.cs (99%) rename osu.Game/Screens/Multi/{Screens/Match/Match.cs => Match/MatchScreen.cs} (87%) rename osu.Game/Screens/Multi/{Screens => }/MultiplayerScreen.cs (97%) diff --git a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs index 8fd8880fd6..bcebf0a8d9 100644 --- a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs +++ b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs @@ -9,7 +9,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Screens.Multi.Components; +using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Users; namespace osu.Game.Tests.Visual diff --git a/osu.Game.Tests/Visual/TestCaseLounge.cs b/osu.Game.Tests/Visual/TestCaseLounge.cs index e0e6332ef0..ecf7c5194c 100644 --- a/osu.Game.Tests/Visual/TestCaseLounge.cs +++ b/osu.Game.Tests/Visual/TestCaseLounge.cs @@ -10,8 +10,8 @@ using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; using osu.Game.Screens; using osu.Game.Screens.Backgrounds; -using osu.Game.Screens.Multi.Components; -using osu.Game.Screens.Multi.Screens.Lounge; +using osu.Game.Screens.Multi.Lounge; +using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Users; using osuTK.Input; @@ -20,12 +20,12 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseLounge : ManualInputManagerTestCase { - private TestLounge lounge; + private TestLoungeScreen loungeScreen; [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - lounge = new TestLounge(); + loungeScreen = new TestLoungeScreen(); Room[] rooms = { @@ -159,47 +159,47 @@ namespace osu.Game.Tests.Visual }, }; - AddStep(@"show", () => Add(lounge)); - AddStep(@"set rooms", () => lounge.Rooms = rooms); + AddStep(@"show", () => Add(loungeScreen)); + AddStep(@"set rooms", () => loungeScreen.Rooms = rooms); selectAssert(0); - AddStep(@"clear rooms", () => lounge.Rooms = new Room[] {}); - AddAssert(@"no room selected", () => lounge.SelectedRoom == null); - AddStep(@"set rooms", () => lounge.Rooms = rooms); + AddStep(@"clear rooms", () => loungeScreen.Rooms = new Room[] {}); + AddAssert(@"no room selected", () => loungeScreen.SelectedRoom == null); + AddStep(@"set rooms", () => loungeScreen.Rooms = rooms); selectAssert(1); AddStep(@"open room 1", () => clickRoom(1)); - AddUntilStep(() => lounge.ChildScreen?.IsCurrentScreen == true, "wait until room current"); - AddStep(@"make lounge current", lounge.MakeCurrent); + AddUntilStep(() => loungeScreen.ChildScreen?.IsCurrentScreen == true, "wait until room current"); + AddStep(@"make lounge current", loungeScreen.MakeCurrent); filterAssert(@"THE FINAL", LoungeTab.Public, 1); filterAssert(string.Empty, LoungeTab.Public, 2); filterAssert(string.Empty, LoungeTab.Private, 1); filterAssert(string.Empty, LoungeTab.Public, 2); filterAssert(@"no matches", LoungeTab.Public, 0); - AddStep(@"clear rooms", () => lounge.Rooms = new Room[] {}); - AddStep(@"set rooms", () => lounge.Rooms = rooms); - AddAssert(@"no matches after clear", () => !lounge.ChildRooms.Any()); + AddStep(@"clear rooms", () => loungeScreen.Rooms = new Room[] {}); + AddStep(@"set rooms", () => loungeScreen.Rooms = rooms); + AddAssert(@"no matches after clear", () => !loungeScreen.ChildRooms.Any()); filterAssert(string.Empty, LoungeTab.Public, 2); - AddStep(@"exit", lounge.Exit); + AddStep(@"exit", loungeScreen.Exit); } private void clickRoom(int n) { - InputManager.MoveMouseTo(lounge.ChildRooms.ElementAt(n)); + InputManager.MoveMouseTo(loungeScreen.ChildRooms.ElementAt(n)); InputManager.Click(MouseButton.Left); } private void selectAssert(int n) { AddStep($@"select room {n}", () => clickRoom(n)); - AddAssert($@"room {n} selected", () => lounge.SelectedRoom == lounge.ChildRooms.ElementAt(n).Room); + AddAssert($@"room {n} selected", () => loungeScreen.SelectedRoom == loungeScreen.ChildRooms.ElementAt(n).Room); } private void filterAssert(string filter, LoungeTab tab, int endCount) { - AddStep($@"filter '{filter}', {tab}", () => lounge.SetFilter(filter, tab)); - AddAssert(@"filtered correctly", () => lounge.ChildRooms.Count() == endCount); + AddStep($@"filter '{filter}', {tab}", () => loungeScreen.SetFilter(filter, tab)); + AddAssert(@"filtered correctly", () => loungeScreen.ChildRooms.Count() == endCount); } - private class TestLounge : Lounge + private class TestLoungeScreen : LoungeScreen { protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault(); diff --git a/osu.Game.Tests/Visual/TestCaseMatch.cs b/osu.Game.Tests/Visual/TestCaseMatch.cs index 6099ed41bb..fd4806ac90 100644 --- a/osu.Game.Tests/Visual/TestCaseMatch.cs +++ b/osu.Game.Tests/Visual/TestCaseMatch.cs @@ -8,8 +8,8 @@ using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Screens.Multi.Components; -using osu.Game.Screens.Multi.Screens.Match; +using osu.Game.Screens.Multi.Match; +using osu.Game.Screens.Multi.Match.Components; using osu.Game.Users; namespace osu.Game.Tests.Visual @@ -96,9 +96,9 @@ namespace osu.Game.Tests.Visual }, }; - Match match = new Match(room); + MatchScreen matchScreen = new MatchScreen(room); - AddStep(@"show", () => Add(match)); + AddStep(@"show", () => Add(matchScreen)); AddStep(@"null beatmap", () => room.Beatmap.Value = null); AddStep(@"change name", () => room.Name.Value = @"Two Awesome Rooms"); AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying()); @@ -146,7 +146,7 @@ namespace osu.Game.Tests.Visual }, }); - AddStep(@"exit", match.Exit); + AddStep(@"exit", matchScreen.Exit); } } } diff --git a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs index 6998ff4c39..37b3f6030d 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs @@ -6,7 +6,7 @@ using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Screens.Multi.Screens.Match; +using osu.Game.Screens.Multi.Match.Components; namespace osu.Game.Tests.Visual { diff --git a/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs index 6024ec8ea6..67a56e525f 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs @@ -3,7 +3,7 @@ using NUnit.Framework; using osu.Framework.Graphics; -using osu.Game.Screens.Multi.Screens.Match; +using osu.Game.Screens.Multi.Match.Components; using osu.Game.Users; namespace osu.Game.Tests.Visual diff --git a/osu.Game.Tests/Visual/TestCaseMultiHeader.cs b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs index d27a447077..e416000f31 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiHeader.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs @@ -4,7 +4,7 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Game.Screens.Multi; -using osu.Game.Screens.Multi.Screens.Lounge; +using osu.Game.Screens.Multi.Lounge; namespace osu.Game.Tests.Visual { @@ -13,14 +13,14 @@ namespace osu.Game.Tests.Visual { public TestCaseMultiHeader() { - Lounge lounge; + LoungeScreen loungeScreen; Children = new Drawable[] { - lounge = new Lounge + loungeScreen = new LoungeScreen { Padding = new MarginPadding { Top = Header.HEIGHT }, }, - new Header(lounge), + new Header(loungeScreen), }; } } diff --git a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs index 9df057806e..c65ab4e3e3 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs @@ -5,7 +5,8 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Game.Screens.Multi; -using osu.Game.Screens.Multi.Screens.Lounge; +using osu.Game.Screens.Multi.Lounge; +using osu.Game.Screens.Multi.Lounge.Components; namespace osu.Game.Tests.Visual { @@ -15,7 +16,7 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(Multiplayer), - typeof(Lounge), + typeof(LoungeScreen), typeof(FilterControl) }; diff --git a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs index 06b9c4a6f9..57ed8419df 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Screens.Multi.Components; +using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Users; namespace osu.Game.Tests.Visual diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index b0b287fdb3..19e27ddefe 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -8,8 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing.Input; using osu.Game.Online.Multiplayer; -using osu.Game.Screens.Multi.Components; -using osu.Game.Screens.Multi.Screens.Match; +using osu.Game.Screens.Multi.Match.Components; using osuTK.Input; namespace osu.Game.Tests.Visual diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 612a3e6993..8e5a7381e9 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -10,7 +10,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.SearchableList; -using osu.Game.Screens.Multi.Screens; using osuTK; using osuTK.Graphics; diff --git a/osu.Game/Screens/Multi/Screens/IMultiplayerScreen.cs b/osu.Game/Screens/Multi/IMultiplayerScreen.cs similarity index 85% rename from osu.Game/Screens/Multi/Screens/IMultiplayerScreen.cs rename to osu.Game/Screens/Multi/IMultiplayerScreen.cs index 0b6ebc3716..c1f43fa30d 100644 --- a/osu.Game/Screens/Multi/Screens/IMultiplayerScreen.cs +++ b/osu.Game/Screens/Multi/IMultiplayerScreen.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -namespace osu.Game.Screens.Multi.Screens +namespace osu.Game.Screens.Multi { public interface IMultiplayerScreen { diff --git a/osu.Game/Screens/Multi/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs similarity index 99% rename from osu.Game/Screens/Multi/Components/DrawableRoom.cs rename to osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index 9425457670..57ce9fc0b9 100644 --- a/osu.Game/Screens/Multi/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -17,11 +17,12 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Components; using osu.Game.Users; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Components +namespace osu.Game.Screens.Multi.Lounge.Components { public class DrawableRoom : OsuClickableContainer, IStateful, IFilterable { diff --git a/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs similarity index 95% rename from osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs rename to osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs index 301e235b79..fdc6c6f693 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs @@ -6,7 +6,7 @@ using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Screens.Lounge +namespace osu.Game.Screens.Multi.Lounge.Components { public class FilterControl : SearchableListFilterControl { diff --git a/osu.Game/Screens/Multi/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs similarity index 99% rename from osu.Game/Screens/Multi/Components/ParticipantInfo.cs rename to osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs index 47aff3f200..3bc20b58c5 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Users; using osuTK; -namespace osu.Game.Screens.Multi.Components +namespace osu.Game.Screens.Multi.Lounge.Components { public class ParticipantInfo : Container { diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs similarity index 99% rename from osu.Game/Screens/Multi/Components/RoomInspector.cs rename to osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 07cf5541c5..496d8b52ca 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -17,11 +17,12 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Components; using osu.Game.Users; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Components +namespace osu.Game.Screens.Multi.Lounge.Components { public class RoomInspector : Container { diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs similarity index 95% rename from osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs rename to osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index 19205065bc..3e81c7d652 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -11,12 +11,13 @@ using osu.Framework.Screens; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; -using osu.Game.Screens.Multi.Components; +using osu.Game.Screens.Multi.Lounge.Components; +using osu.Game.Screens.Multi.Match; using osuTK; -namespace osu.Game.Screens.Multi.Screens.Lounge +namespace osu.Game.Screens.Multi.Lounge { - public class Lounge : MultiplayerScreen + public class LoungeScreen : MultiplayerScreen { private readonly Container content; private readonly SearchContainer search; @@ -32,7 +33,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge protected override Drawable TransitionContent => content; - public Lounge() + public LoungeScreen() { Children = new Drawable[] { @@ -164,7 +165,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge Filter.Tabs.Current.Value = LoungeTab.Public; - Push(new Match.Match(roomBeingCreated)); + Push(new MatchScreen(roomBeingCreated)); } search.SearchTerm = Filter.Search.Current.Value ?? string.Empty; @@ -194,7 +195,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge RoomsContainer.ForEach(c => c.State = c == room ? SelectionState.Selected : SelectionState.NotSelected); Inspector.Room = room.Room; - Push(new Match.Match(room.Room)); + Push(new MatchScreen(room.Room)); } private class RoomsFilterContainer : FillFlowContainer, IHasFilterableChildren diff --git a/osu.Game/Screens/Multi/Components/GameTypePicker.cs b/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs similarity index 97% rename from osu.Game/Screens/Multi/Components/GameTypePicker.cs rename to osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs index d9619ad35d..aec26a751e 100644 --- a/osu.Game/Screens/Multi/Components/GameTypePicker.cs +++ b/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs @@ -9,9 +9,10 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Components; using osuTK; -namespace osu.Game.Screens.Multi.Components +namespace osu.Game.Screens.Multi.Match.Components { public class GameTypePicker : DisableableTabControl { diff --git a/osu.Game/Screens/Multi/Screens/Match/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs similarity index 98% rename from osu.Game/Screens/Multi/Screens/Match/Header.cs rename to osu.Game/Screens/Multi/Match/Components/Header.cs index 7d3525370f..9c72403806 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -17,7 +17,7 @@ using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Screens.Match +namespace osu.Game.Screens.Multi.Match.Components { public class Header : Container { diff --git a/osu.Game/Screens/Multi/Screens/Match/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs similarity index 99% rename from osu.Game/Screens/Multi/Screens/Match/Info.cs rename to osu.Game/Screens/Multi/Match/Components/Info.cs index d479765159..b3de5abf67 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -17,7 +17,7 @@ using osu.Game.Overlays.SearchableList; using osu.Game.Screens.Multi.Components; using osuTK; -namespace osu.Game.Screens.Multi.Screens.Match +namespace osu.Game.Screens.Multi.Match.Components { public class Info : Container { diff --git a/osu.Game/Screens/Multi/Screens/Match/MatchPage.cs b/osu.Game/Screens/Multi/Match/Components/MatchPage.cs similarity index 93% rename from osu.Game/Screens/Multi/Screens/Match/MatchPage.cs rename to osu.Game/Screens/Multi/Match/Components/MatchPage.cs index 710e41ec69..54ba345934 100644 --- a/osu.Game/Screens/Multi/Screens/Match/MatchPage.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchPage.cs @@ -3,7 +3,7 @@ using osu.Framework.Configuration; -namespace osu.Game.Screens.Multi.Screens.Match +namespace osu.Game.Screens.Multi.Match.Components { public abstract class MatchPage { diff --git a/osu.Game/Screens/Multi/Screens/Match/MatchTabControl.cs b/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs similarity index 97% rename from osu.Game/Screens/Multi/Screens/Match/MatchTabControl.cs rename to osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs index 5fd64179cd..51698fa50f 100644 --- a/osu.Game/Screens/Multi/Screens/Match/MatchTabControl.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Screens.Match +namespace osu.Game.Screens.Multi.Match.Components { public class MatchTabControl : PageTabControl { diff --git a/osu.Game/Screens/Multi/Screens/Match/Participants.cs b/osu.Game/Screens/Multi/Match/Components/Participants.cs similarity index 98% rename from osu.Game/Screens/Multi/Screens/Match/Participants.cs rename to osu.Game/Screens/Multi/Match/Components/Participants.cs index 98ab758f81..92732dc045 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Participants.cs +++ b/osu.Game/Screens/Multi/Match/Components/Participants.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Multi.Components; using osu.Game.Users; using osuTK; -namespace osu.Game.Screens.Multi.Screens.Match +namespace osu.Game.Screens.Multi.Match.Components { public class Participants : CompositeDrawable { diff --git a/osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs b/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs similarity index 97% rename from osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs rename to osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs index 287add5de1..4ddc9b30e9 100644 --- a/osu.Game/Screens/Multi/Components/RoomAvailabilityPicker.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs @@ -10,10 +10,11 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Components; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Components +namespace osu.Game.Screens.Multi.Match.Components { public class RoomAvailabilityPicker : DisableableTabControl { diff --git a/osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs similarity index 99% rename from osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs rename to osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index 747c109e3f..56990403c2 100644 --- a/osu.Game/Screens/Multi/Screens/Match/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -12,11 +12,10 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; -using osu.Game.Screens.Multi.Components; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Multi.Screens.Match +namespace osu.Game.Screens.Multi.Match.Components { public class RoomSettingsOverlay : FocusedOverlayContainer { diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs similarity index 87% rename from osu.Game/Screens/Multi/Screens/Match/Match.cs rename to osu.Game/Screens/Multi/Match/MatchScreen.cs index 40590a6982..755b071f30 100644 --- a/osu.Game/Screens/Multi/Screens/Match/Match.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -9,12 +9,13 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Select; using osu.Game.Users; -namespace osu.Game.Screens.Multi.Screens.Match +namespace osu.Game.Screens.Multi.Match { - public class Match : MultiplayerScreen + public class MatchScreen : MultiplayerScreen { private readonly Participants participants; @@ -41,7 +42,7 @@ namespace osu.Game.Screens.Multi.Screens.Match [Resolved] private APIAccess api { get; set; } - public Match(Room room) + public MatchScreen(Room room) { this.room = room; @@ -53,29 +54,29 @@ namespace osu.Game.Screens.Multi.Screens.Match participantsBind.BindTo(room.Participants); maxParticipantsBind.BindTo(room.MaxParticipants); - Header header; + Components.Header header; RoomSettingsOverlay settings; Info info; Children = new Drawable[] { - header = new Header + header = new Components.Header { Depth = -1, }, info = new Info { - Margin = new MarginPadding { Top = Header.HEIGHT }, + Margin = new MarginPadding { Top = Components.Header.HEIGHT }, }, participants = new Participants { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = Header.HEIGHT + Info.HEIGHT }, + Padding = new MarginPadding { Top = Components.Header.HEIGHT + Info.HEIGHT }, }, new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = Header.HEIGHT }, + Padding = new MarginPadding { Top = Components.Header.HEIGHT }, Child = settings = new RoomSettingsOverlay { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 7822fa68dc..d90e9ea33d 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Screens.Menu; -using osu.Game.Screens.Multi.Screens.Lounge; +using osu.Game.Screens.Multi.Lounge; namespace osu.Game.Screens.Multi { @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Multi RelativeSizeAxes = Axes.Both, }; - Lounge lounge; + LoungeScreen loungeScreen; Children = new Drawable[] { new Container @@ -53,12 +53,12 @@ namespace osu.Game.Screens.Multi { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Header.HEIGHT }, - Child = lounge = new Lounge(), + Child = loungeScreen = new LoungeScreen(), }, - new Header(lounge), + new Header(loungeScreen), }; - lounge.Exited += s => Exit(); + loungeScreen.Exited += s => Exit(); } protected override void OnEntering(Screen last) diff --git a/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs b/osu.Game/Screens/Multi/MultiplayerScreen.cs similarity index 97% rename from osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs rename to osu.Game/Screens/Multi/MultiplayerScreen.cs index 3184316a33..da9a2b3051 100644 --- a/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs +++ b/osu.Game/Screens/Multi/MultiplayerScreen.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics; using osu.Framework.Screens; using osu.Game.Graphics.Containers; -namespace osu.Game.Screens.Multi.Screens +namespace osu.Game.Screens.Multi { public abstract class MultiplayerScreen : OsuScreen, IMultiplayerScreen { diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 28525215fb..94ac951159 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Screens.Multi.Screens; +using osu.Game.Screens.Multi; namespace osu.Game.Screens.Select { From bf3f5ab6854f0692e0a55f728b028d4a1f261f9c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Dec 2018 17:32:01 +0900 Subject: [PATCH 036/220] Change ready button to "Start" and make it enter player --- osu.Game/Screens/Multi/Header.cs | 7 ++- .../Screens/Multi/Match/Components/Info.cs | 63 ++----------------- .../Multi/Match/Components/ReadyButton.cs | 50 +++++++++++++++ osu.Game/Screens/Multi/Match/MatchScreen.cs | 17 +++++ osu.Game/Screens/Multi/Multiplayer.cs | 18 +++--- .../Screens/Multi/Play/TimeshiftPlayer.cs | 11 ++++ 6 files changed, 100 insertions(+), 66 deletions(-) create mode 100644 osu.Game/Screens/Multi/Match/Components/ReadyButton.cs create mode 100644 osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 8e5a7381e9..570db11d50 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -85,7 +85,12 @@ namespace osu.Game.Screens.Multi }, }; - breadcrumbs.Current.ValueChanged += s => screenType.Text = ((IMultiplayerScreen)s).ShortTitle.ToLowerInvariant(); + breadcrumbs.Current.ValueChanged += s => + { + if (s is IMultiplayerScreen mpScreen) + screenType.Text = mpScreen.ShortTitle.ToLowerInvariant(); + }; + breadcrumbs.Current.TriggerChange(); } diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index b3de5abf67..f13bf710e6 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -1,17 +1,16 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; using osu.Game.Screens.Multi.Components; @@ -23,13 +22,12 @@ namespace osu.Game.Screens.Multi.Match.Components { public const float HEIGHT = 128; + public Action OnStart; + private readonly OsuSpriteText availabilityStatus; - private readonly ReadyButton readyButton; private OsuColour colours; - public Bindable Ready => readyButton.Ready; - public readonly Bindable Name = new Bindable(); public readonly Bindable Availability = new Bindable(); public readonly Bindable Status = new Bindable(); @@ -81,13 +79,14 @@ namespace osu.Game.Screens.Multi.Match.Components }, }, }, - readyButton = new ReadyButton + new ReadyButton { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, Size = new Vector2(200, 1), Padding = new MarginPadding { Vertical = 10 }, + Action = () => OnStart?.Invoke() }, }, }, @@ -125,57 +124,5 @@ namespace osu.Game.Screens.Multi.Match.Components availabilityStatus.Text = $"{Availability.Value.GetDescription()}, {Status.Value.Message}"; } } - - private class ReadyButton : TriangleButton - { - public readonly Bindable Ready = new Bindable(); - - protected override SpriteText CreateText() => new OsuSpriteText - { - Depth = -1, - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Font = @"Exo2.0-Light", - TextSize = 30, - }; - - [BackgroundDependencyLoader] - private void load() - { - BackgroundColour = OsuColour.FromHex(@"1187aa"); - Triangles.ColourLight = OsuColour.FromHex(@"277b9c"); - Triangles.ColourDark = OsuColour.FromHex(@"1f6682"); - Triangles.TriangleScale = 1.5f; - - Container active; - Add(active = new Container - { - RelativeSizeAxes = Axes.Both, - Alpha = 0f, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0.15f, - Blending = BlendingMode.Additive, - }, - }); - - Action = () => Ready.Value = !Ready.Value; - - Ready.BindValueChanged(value => - { - if (value) - { - Text = "Not Ready"; - active.FadeIn(200); - } - else - { - Text = "Ready"; - active.FadeOut(200); - } - }, true); - } - } } } diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs new file mode 100644 index 0000000000..f0ca013b62 --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class ReadyButton : TriangleButton + { + [BackgroundDependencyLoader] + private void load() + { + BackgroundColour = OsuColour.FromHex(@"1187aa"); + + Triangles.ColourLight = OsuColour.FromHex(@"277b9c"); + Triangles.ColourDark = OsuColour.FromHex(@"1f6682"); + Triangles.TriangleScale = 1.5f; + + Text = "Start"; + + Add(new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 1f, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.15f, + Blending = BlendingMode.Additive, + }, + }); + } + + protected override SpriteText CreateText() => new OsuSpriteText + { + Depth = -1, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Font = @"Exo2.0-Light", + TextSize = 30, + }; + } +} diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 755b071f30..bbc4e2f4e0 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -10,6 +10,8 @@ using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Screens.Multi.Play; +using osu.Game.Screens.Play; using osu.Game.Screens.Select; using osu.Game.Users; @@ -36,6 +38,9 @@ namespace osu.Game.Screens.Multi.Match [Cached] private readonly Room room; + [Resolved] + private Multiplayer multiplayer { get; set; } + [Resolved] private BeatmapManager beatmapManager { get; set; } @@ -67,6 +72,7 @@ namespace osu.Game.Screens.Multi.Match info = new Info { Margin = new MarginPadding { Top = Components.Header.HEIGHT }, + OnStart = onStart }, participants = new Participants { @@ -113,5 +119,16 @@ namespace osu.Game.Screens.Multi.Match beatmapBind.BindValueChanged(b => Beatmap.Value = beatmapManager.GetWorkingBeatmap(room.Beatmap.Value), true); Beatmap.BindValueChanged(b => beatmapBind.Value = b.BeatmapInfo); } + + private void onStart() + { + switch (typeBind.Value) + { + default: + case GameTypeTimeshift _: + multiplayer.Push(new PlayerLoader(new TimeshiftPlayer())); + break; + } + } } } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index d90e9ea33d..566621ffcd 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -13,21 +14,20 @@ using osu.Game.Screens.Multi.Lounge; namespace osu.Game.Screens.Multi { + [Cached] public class Multiplayer : OsuScreen { private readonly MultiplayerWaveContainer waves; - protected override Container Content => waves; - public Multiplayer() { - InternalChild = waves = new MultiplayerWaveContainer + Child = waves = new MultiplayerWaveContainer { RelativeSizeAxes = Axes.Both, }; LoungeScreen loungeScreen; - Children = new Drawable[] + waves.AddRange(new Drawable[] { new Container { @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Multi Child = loungeScreen = new LoungeScreen(), }, new Header(loungeScreen), - }; + }); loungeScreen.Exited += s => Exit(); } @@ -76,13 +76,17 @@ namespace osu.Game.Screens.Multi protected override void OnResuming(Screen last) { base.OnResuming(last); - waves.Show(); + + Content.FadeIn(250); + Content.ScaleTo(1, 250, Easing.OutSine); } protected override void OnSuspending(Screen next) { + Content.ScaleTo(1.1f, 250, Easing.InSine); + Content.FadeOut(250); + base.OnSuspending(next); - waves.Hide(); } protected override void LogoExiting(OsuLogo logo) diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs new file mode 100644 index 0000000000..114d90dc79 --- /dev/null +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Screens.Play; + +namespace osu.Game.Screens.Multi.Play +{ + public class TimeshiftPlayer : Player + { + } +} From 497f431366fa27bb6ddcd1df176d4cd4def55ead Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Dec 2018 19:07:40 +0900 Subject: [PATCH 037/220] Implement RoomManager and RoomsContainer Reduces logic from LoungeScreen --- osu.Game.Tests/Visual/TestCaseLounge.cs | 18 +-- .../Visual/TestCaseRoomInspector.cs | 8 +- .../Multi/Lounge/Components/FilterControl.cs | 4 +- .../Multi/Lounge/Components/FilterCriteria.cs | 12 ++ .../Multi/Lounge/Components/RoomInspector.cs | 112 +++++++---------- .../Multi/Lounge/Components/RoomsContainer.cs | 104 +++++++++++++++ osu.Game/Screens/Multi/Lounge/LoungeScreen.cs | 118 +++--------------- .../Match/Components/RoomSettingsOverlay.cs | 8 +- osu.Game/Screens/Multi/Multiplayer.cs | 2 +- osu.Game/Screens/Multi/RoomManager.cs | 32 +++++ 10 files changed, 229 insertions(+), 189 deletions(-) create mode 100644 osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs create mode 100644 osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs create mode 100644 osu.Game/Screens/Multi/RoomManager.cs diff --git a/osu.Game.Tests/Visual/TestCaseLounge.cs b/osu.Game.Tests/Visual/TestCaseLounge.cs index ecf7c5194c..c1253e4f5c 100644 --- a/osu.Game.Tests/Visual/TestCaseLounge.cs +++ b/osu.Game.Tests/Visual/TestCaseLounge.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; -using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Game.Beatmaps; @@ -10,6 +8,7 @@ using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; using osu.Game.Screens; using osu.Game.Screens.Backgrounds; +using osu.Game.Screens.Multi; using osu.Game.Screens.Multi.Lounge; using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Users; @@ -160,11 +159,8 @@ namespace osu.Game.Tests.Visual }; AddStep(@"show", () => Add(loungeScreen)); - AddStep(@"set rooms", () => loungeScreen.Rooms = rooms); selectAssert(0); - AddStep(@"clear rooms", () => loungeScreen.Rooms = new Room[] {}); AddAssert(@"no room selected", () => loungeScreen.SelectedRoom == null); - AddStep(@"set rooms", () => loungeScreen.Rooms = rooms); selectAssert(1); AddStep(@"open room 1", () => clickRoom(1)); AddUntilStep(() => loungeScreen.ChildScreen?.IsCurrentScreen == true, "wait until room current"); @@ -174,37 +170,33 @@ namespace osu.Game.Tests.Visual filterAssert(string.Empty, LoungeTab.Private, 1); filterAssert(string.Empty, LoungeTab.Public, 2); filterAssert(@"no matches", LoungeTab.Public, 0); - AddStep(@"clear rooms", () => loungeScreen.Rooms = new Room[] {}); - AddStep(@"set rooms", () => loungeScreen.Rooms = rooms); - AddAssert(@"no matches after clear", () => !loungeScreen.ChildRooms.Any()); filterAssert(string.Empty, LoungeTab.Public, 2); AddStep(@"exit", loungeScreen.Exit); } private void clickRoom(int n) { - InputManager.MoveMouseTo(loungeScreen.ChildRooms.ElementAt(n)); InputManager.Click(MouseButton.Left); } private void selectAssert(int n) { AddStep($@"select room {n}", () => clickRoom(n)); - AddAssert($@"room {n} selected", () => loungeScreen.SelectedRoom == loungeScreen.ChildRooms.ElementAt(n).Room); } private void filterAssert(string filter, LoungeTab tab, int endCount) { AddStep($@"filter '{filter}', {tab}", () => loungeScreen.SetFilter(filter, tab)); - AddAssert(@"filtered correctly", () => loungeScreen.ChildRooms.Count() == endCount); } private class TestLoungeScreen : LoungeScreen { protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault(); - public IEnumerable ChildRooms => RoomsContainer.Children.Where(r => r.MatchingFilter); - public Room SelectedRoom => Inspector.Room; + [Resolved] + private RoomManager manager { get; set; } + + public Room SelectedRoom => manager.Current.Value; public void SetFilter(string filter, LoungeTab tab) { diff --git a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs index 57ed8419df..9f6eea68e7 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs @@ -66,8 +66,7 @@ namespace osu.Game.Tests.Visual } }; - RoomInspector inspector; - Add(inspector = new RoomInspector + Add(new RoomInspector { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -75,9 +74,6 @@ namespace osu.Game.Tests.Visual Width = 0.5f, }); - AddStep(@"set room", () => inspector.Room = room); - AddStep(@"null room", () => inspector.Room = null); - AddStep(@"set room", () => inspector.Room = room); AddStep(@"change title", () => room.Name.Value = @"A Better Room Than The Above"); AddStep(@"change host", () => room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } }); AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying()); @@ -133,8 +129,6 @@ namespace osu.Game.Tests.Visual } } }; - - inspector.Room = newRoom; }); } diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs index fdc6c6f693..ddab9c197e 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs @@ -18,7 +18,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components DisplayStyleControl.Hide(); } - public RoomAvailability Availability + public FilterCriteria CreateCriteria() => new FilterCriteria { Availability = availability }; + + private RoomAvailability availability { get { diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs new file mode 100644 index 0000000000..ec62ef1bdf --- /dev/null +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Online.Multiplayer; + +namespace osu.Game.Screens.Multi.Lounge.Components +{ + public class FilterCriteria + { + public RoomAvailability Availability; + } +} diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 496d8b52ca..e8de201b8f 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -28,6 +28,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components { private const float transition_duration = 100; + public readonly Bindable Room = new Bindable(); + private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; private readonly Bindable nameBind = new Bindable(); private readonly Bindable beatmapBind = new Bindable(); @@ -52,43 +54,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components [Resolved] private BeatmapManager beatmaps { get; set; } - private Room room; - public Room Room - { - get => room; - set - { - if (value == room) - return; - - if (room != null) - { - nameBind.UnbindFrom(room.Name); - hostBind.UnbindFrom(room.Host); - statusBind.UnbindFrom(room.Status); - typeBind.UnbindFrom(room.Type); - beatmapBind.UnbindFrom(room.Beatmap); - maxParticipantsBind.UnbindFrom(room.MaxParticipants); - participantsBind.UnbindFrom(room.Participants); - } - - room = value; - - if (room != null) - { - nameBind.BindTo(room.Name); - hostBind.BindTo(room.Host); - statusBind.BindTo(room.Status); - typeBind.BindTo(room.Type); - beatmapBind.BindTo(room.Beatmap); - maxParticipantsBind.BindTo(room.MaxParticipants); - participantsBind.BindTo(room.Participants); - } - - updateState(); - } - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -226,7 +191,52 @@ namespace osu.Game.Screens.Multi.Lounge.Components beatmapTypeInfo.Type.BindTo(typeBind); beatmapTypeInfo.Beatmap.BindTo(beatmapBind); - updateState(); + Room.BindValueChanged(updateRoom, true); + } + + private Room lastRoom; + + private void updateRoom(Room newRoom) + { + if (lastRoom != null) + { + nameBind.UnbindFrom(lastRoom.Name); + hostBind.UnbindFrom(lastRoom.Host); + statusBind.UnbindFrom(lastRoom.Status); + typeBind.UnbindFrom(lastRoom.Type); + beatmapBind.UnbindFrom(lastRoom.Beatmap); + maxParticipantsBind.UnbindFrom(lastRoom.MaxParticipants); + participantsBind.UnbindFrom(lastRoom.Participants); + } + + if (newRoom != null) + { + nameBind.BindTo(newRoom.Name); + hostBind.BindTo(newRoom.Host); + statusBind.BindTo(newRoom.Status); + typeBind.BindTo(newRoom.Type); + beatmapBind.BindTo(newRoom.Beatmap); + maxParticipantsBind.BindTo(newRoom.MaxParticipants); + participantsBind.BindTo(newRoom.Participants); + + participantsFlow.FadeIn(transition_duration); + participantCount.FadeIn(transition_duration); + beatmapTypeInfo.FadeIn(transition_duration); + name.FadeIn(transition_duration); + participantInfo.FadeIn(transition_duration); + } + else + { + participantsFlow.FadeOut(transition_duration); + participantCount.FadeOut(transition_duration); + beatmapTypeInfo.FadeOut(transition_duration); + name.FadeOut(transition_duration); + participantInfo.FadeOut(transition_duration); + + displayStatus(new RoomStatusNoneSelected()); + } + + lastRoom = newRoom; } protected override void UpdateAfterChildren() @@ -245,32 +255,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components status.FadeColour(c, transition_duration); } - private void updateState() - { - if (Room == null) - { - beatmap.Value = null; - participantsFlow.FadeOut(transition_duration); - participantCount.FadeOut(transition_duration); - beatmapTypeInfo.FadeOut(transition_duration); - name.FadeOut(transition_duration); - participantInfo.FadeOut(transition_duration); - - displayStatus(new RoomStatusNoneSelected()); - } - else - { - participantsFlow.FadeIn(transition_duration); - participantCount.FadeIn(transition_duration); - beatmapTypeInfo.FadeIn(transition_duration); - name.FadeIn(transition_duration); - participantInfo.FadeIn(transition_duration); - - statusBind.TriggerChange(); - beatmapBind.TriggerChange(); - } - } - private class UserTile : Container, IHasTooltip { private readonly User user; diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs new file mode 100644 index 0000000000..072a892954 --- /dev/null +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -0,0 +1,104 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Multiplayer; +using osuTK; + +namespace osu.Game.Screens.Multi.Lounge.Components +{ + public class RoomsContainer : CompositeDrawable, IHasFilterableChildren + { + public Action OpenRequested; + + private readonly IBindableCollection rooms = new BindableCollection(); + private readonly Bindable currentRoom = new Bindable(); + + private readonly FillFlowContainer roomFlow; + + [Resolved] + private RoomManager manager { get; set; } + + public RoomsContainer() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChild = roomFlow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(2), + }; + } + + [BackgroundDependencyLoader] + private void load() + { + currentRoom.BindTo(manager.Current); + rooms.BindTo(manager.Rooms); + + rooms.ItemsAdded += addRooms; + rooms.ItemsRemoved += removeRooms; + + addRooms(rooms); + + currentRoom.BindValueChanged(selectRoom, true); + } + + private FilterCriteria currentFilter; + + public void Filter(FilterCriteria criteria) + { + roomFlow.Children.ForEach(r => r.MatchingFilter = criteria == null || r.Room.Availability == criteria.Availability); + currentFilter = criteria; + } + + private void addRooms(IEnumerable rooms) + { + foreach (var r in rooms) + roomFlow.Add(new DrawableRoom(r) { Action = () => selectRoom(r) }); + + Filter(currentFilter); + } + + private void removeRooms(IEnumerable rooms) + { + foreach (var r in rooms) + { + var toRemove = roomFlow.Single(d => d.Room == r); + toRemove.Action = null; + + roomFlow.Remove(toRemove); + } + } + + private void selectRoom(Room room) + { + var drawable = roomFlow.FirstOrDefault(r => r.Room == room); + + if (drawable != null && drawable.State == SelectionState.Selected) + OpenRequested?.Invoke(room); + else + { + currentRoom.Value = room; + roomFlow.Children.ForEach(r => r.State = r.Room == room ? SelectionState.Selected : SelectionState.NotSelected); + } + } + + public IEnumerable FilterTerms => Enumerable.Empty(); + + public IEnumerable FilterableChildren => InternalChildren.OfType(); + + public bool MatchingFilter { set { } } + } +} diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index 3e81c7d652..1b49e0c1b3 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -1,40 +1,37 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; -using osu.Framework.Configuration; -using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osu.Framework.Screens; -using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Screens.Multi.Match; -using osuTK; namespace osu.Game.Screens.Multi.Lounge { public class LoungeScreen : MultiplayerScreen { + protected readonly FilterControl Filter; + private readonly Container content; private readonly SearchContainer search; + private readonly RoomsContainer rooms; - protected readonly FilterControl Filter; - protected readonly FillFlowContainer RoomsContainer; - protected readonly RoomInspector Inspector; + [Cached] + private readonly RoomManager manager; public override string Title => "Lounge"; - private Room roomBeingCreated; - private readonly IBindable roomCreated = new Bindable(); - protected override Drawable TransitionContent => content; public LoungeScreen() { + RoomInspector inspector; + Children = new Drawable[] { Filter = new FilterControl { Depth = -1 }, @@ -56,16 +53,10 @@ namespace osu.Game.Screens.Multi.Lounge { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = RoomsContainer = new RoomsFilterContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(10 - DrawableRoom.SELECTION_BORDER_WIDTH * 2), - }, + Child = rooms = new RoomsContainer { OpenRequested = openRoom } }, }, - Inspector = new RoomInspector + inspector = new RoomInspector { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -73,18 +64,15 @@ namespace osu.Game.Screens.Multi.Lounge Width = 0.45f, }, }, - } + }, + manager = new RoomManager() }; + inspector.Room.BindTo(manager.Current); + Filter.Search.Current.ValueChanged += s => filterRooms(); Filter.Tabs.Current.ValueChanged += t => filterRooms(); Filter.Search.Exit += Exit; - - roomCreated.BindValueChanged(v => - { - if (v) - addRoom(roomBeingCreated); - }); } protected override void UpdateAfterChildren() @@ -99,31 +87,6 @@ namespace osu.Game.Screens.Multi.Lounge }; } - public IEnumerable Rooms - { - set - { - RoomsContainer.ForEach(r => r.Action = null); - RoomsContainer.Clear(); - - foreach (var room in value) - addRoom(room); - } - } - - private DrawableRoom addRoom(Room room) - { - var drawableRoom = new DrawableRoom(room); - - drawableRoom.Action = () => selectionRequested(drawableRoom); - - RoomsContainer.Add(drawableRoom); - - filterRooms(); - - return drawableRoom; - } - protected override void OnFocus(FocusEvent e) { GetContainingInputManager().ChangeFocus(Filter.Search); @@ -158,65 +121,22 @@ namespace osu.Game.Screens.Multi.Lounge { if (Filter.Tabs.Current.Value == LoungeTab.Create) { - roomBeingCreated = new Room(); - - roomCreated.UnbindBindings(); - roomCreated.BindTo(roomBeingCreated.Created); - Filter.Tabs.Current.Value = LoungeTab.Public; - - Push(new MatchScreen(roomBeingCreated)); + Push(new MatchScreen(new Room())); } search.SearchTerm = Filter.Search.Current.Value ?? string.Empty; - foreach (DrawableRoom r in RoomsContainer.Children) - { - r.MatchingFilter = r.MatchingFilter && r.Room.Availability.Value == Filter.Availability; - } + rooms.Filter(Filter.CreateCriteria()); } - private void selectionRequested(DrawableRoom room) - { - if (room.State == SelectionState.Selected) - openRoom(room); - else - { - RoomsContainer.ForEach(c => c.State = c == room ? SelectionState.Selected : SelectionState.NotSelected); - Inspector.Room = room.Room; - } - } - - private void openRoom(DrawableRoom room) + private void openRoom(Room room) { + // Handles the case where a room is clicked 3 times in quick succession if (!IsCurrentScreen) return; - RoomsContainer.ForEach(c => c.State = c == room ? SelectionState.Selected : SelectionState.NotSelected); - Inspector.Room = room.Room; - - Push(new MatchScreen(room.Room)); - } - - private class RoomsFilterContainer : FillFlowContainer, IHasFilterableChildren - { - public IEnumerable FilterTerms => new string[] { }; - public IEnumerable FilterableChildren => Children; - - public bool MatchingFilter - { - set - { - if (value) - InvalidateLayout(); - } - } - - public RoomsFilterContainer() - { - LayoutDuration = 200; - LayoutEasing = Easing.OutQuint; - } + Push(new MatchScreen(room)); } } } diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index 56990403c2..e4eb2046b2 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -27,7 +27,6 @@ namespace osu.Game.Screens.Multi.Match.Components private readonly Bindable availabilityBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); - private readonly Bindable createdBind = new Bindable(); private readonly Container content; @@ -39,6 +38,9 @@ namespace osu.Game.Screens.Multi.Match.Components protected readonly TriangleButton ApplyButton; protected readonly OsuPasswordTextBox PasswordField; + [Resolved] + private RoomManager manager { get; set; } + [Resolved] private Room room { get; set; } @@ -162,7 +164,6 @@ namespace osu.Game.Screens.Multi.Match.Components availabilityBind.BindTo(room.Availability); typeBind.BindTo(room.Type); maxParticipantsBind.BindTo(room.MaxParticipants); - createdBind.BindTo(room.Created); MaxParticipantsField.ReadOnly = true; PasswordField.ReadOnly = true; @@ -210,8 +211,7 @@ namespace osu.Game.Screens.Multi.Match.Components else maxParticipantsBind.Value = null; - // Todo: This should only be set after the room has been created server-side - createdBind.Value = true; + manager.CreateRoom(room); } private class SettingsTextBox : OsuTextBox diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index d90e9ea33d..aba83753cb 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Multi Padding = new MarginPadding { Top = Header.HEIGHT }, Child = loungeScreen = new LoungeScreen(), }, - new Header(loungeScreen), + new Header(loungeScreen) }; loungeScreen.Exited += s => Exit(); diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs new file mode 100644 index 0000000000..9e233f278b --- /dev/null +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.Multiplayer; + +namespace osu.Game.Screens.Multi +{ + public class RoomManager : Component + { + public IBindableCollection Rooms => rooms; + private readonly BindableCollection rooms = new BindableCollection(); + + public readonly Bindable Current = new Bindable(); + + [Resolved] + private APIAccess api { get; set; } + + public void CreateRoom(Room room) + { + room.Host.Value = api.LocalUser; + + // Todo: Perform API request + + room.Created.Value = true; + rooms.Add(room); + } + } +} From 7dc1f5b771fa1f5c9bd88ab53a3162da7278029e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 11 Dec 2018 20:12:30 +0900 Subject: [PATCH 038/220] Add more tests --- .../Visual/TestCasePollingComponent.cs | 110 +++++++++++++----- 1 file changed, 78 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePollingComponent.cs b/osu.Game.Tests/Visual/TestCasePollingComponent.cs index 928c92cb2b..bf129bfd53 100644 --- a/osu.Game.Tests/Visual/TestCasePollingComponent.cs +++ b/osu.Game.Tests/Visual/TestCasePollingComponent.cs @@ -3,10 +3,11 @@ using System; using System.Threading.Tasks; -using osu.Framework.Allocation; +using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Logging; using osu.Game.Graphics.Sprites; using osu.Game.Online; using osuTK; @@ -19,12 +20,16 @@ namespace osu.Game.Tests.Visual private Container pollBox; private TestPoller poller; - [BackgroundDependencyLoader] - private void load() + private const float safety_adjust = 1f; + private int count; + + [SetUp] + public void SetUp() => Schedule(() => { + count = 0; + Children = new Drawable[] { - poller = new TestPoller(), pollBox = new Container { Alpha = 0, @@ -48,41 +53,77 @@ namespace osu.Game.Tests.Visual } } }; + }); - int count = 0; + //[Test] + public void TestInstantPolling() + { + createPoller(true); + AddStep("set poll interval to 1", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust); + checkCount(1); + checkCount(2); + checkCount(3); + + AddStep("set poll interval to 5", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust * 5); + checkCount(4); + checkCount(4); + checkCount(4); + + skip(); + + checkCount(5); + checkCount(5); + + AddStep("set poll interval to 1", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust); + checkCount(6); + checkCount(7); + } + + [Test] + public void TestSlowPolling() + { + createPoller(false); + + AddStep("set poll interval to 1", () => poller.TimeBetweenPolls = TimePerAction * safety_adjust * 5); + checkCount(0); + skip(); + checkCount(0); + skip(); + skip(); + skip(); + skip(); + checkCount(0); + skip(); + skip(); + checkCount(0); + } + + private void skip() => AddStep("skip", () => + { + // could be 4 or 5 at this point due to timing discrepancies (safety_adjust @ 0.2 * 5 ~= 1) + // easiest to just ignore the value at this point and move on. + }); + + private void checkCount(int checkValue) + { + Logger.Log($"value is {count}"); + AddAssert($"count is {checkValue}", () => count == checkValue); + } + + private void createPoller(bool instant) => AddStep("create poller", () => + { + poller?.Expire(); + + Add(poller = instant ? new TestPoller() : new TestSlowPoller()); poller.OnPoll += () => { pollBox.FadeOutFromOne(500); count++; }; + }); - AddStep("set poll to 1 second", () => poller.TimeBetweenPolls = TimePerAction); - - void checkCount(int checkValue) => AddAssert($"count is {checkValue}", () => count == checkValue); - - checkCount(1); - checkCount(2); - checkCount(3); - - AddStep("set poll to 5 second", () => poller.TimeBetweenPolls = TimePerAction * 5); - - checkCount(4); - checkCount(4); - checkCount(4); - checkCount(4); - - checkCount(5); - checkCount(5); - checkCount(5); - - AddStep("set poll to 5 second", () => poller.TimeBetweenPolls = TimePerAction); - - AddAssert("count is 6", () => count == 6); - - } - - protected override double TimePerAction => 500; + protected override double TimePerAction => 5000; public class TestPoller : PollingComponent { @@ -90,9 +131,14 @@ namespace osu.Game.Tests.Visual protected override Task Poll() { - OnPoll?.Invoke(); + Schedule(() => OnPoll?.Invoke()); return base.Poll(); } } + + public class TestSlowPoller : TestPoller + { + protected override Task Poll() => Task.Delay((int)(TimeBetweenPolls / 2f / Clock.Rate)).ContinueWith(_ => base.Poll()); + } } } From 170955110ff9acb96594d8848fad96528070a4b9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Dec 2018 14:38:03 +0900 Subject: [PATCH 039/220] Add mods to the match info --- .../Screens/Multi/Match/Components/Info.cs | 24 ++++++++++++++++--- osu.Game/Screens/Multi/Match/MatchScreen.cs | 6 +++++ osu.Game/Screens/Play/HUD/ModDisplay.cs | 7 ++++-- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index b3de5abf67..fe6343e4db 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions; @@ -14,14 +15,16 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Components; +using osu.Game.Screens.Play.HUD; using osuTK; namespace osu.Game.Screens.Multi.Match.Components { public class Info : Container { - public const float HEIGHT = 128; + public const float HEIGHT = 156; private readonly OsuSpriteText availabilityStatus; private readonly ReadyButton readyButton; @@ -35,6 +38,7 @@ namespace osu.Game.Screens.Multi.Match.Components public readonly Bindable Status = new Bindable(); public readonly Bindable Beatmap = new Bindable(); public readonly Bindable Type = new Bindable(); + public readonly Bindable> Mods = new Bindable>(); public Info() { @@ -43,6 +47,7 @@ namespace osu.Game.Screens.Multi.Match.Components BeatmapTypeInfo beatmapTypeInfo; OsuSpriteText name; + ModDisplay modDisplay; Children = new Drawable[] { @@ -74,11 +79,23 @@ namespace osu.Game.Screens.Multi.Match.Components availabilityStatus = new OsuSpriteText { TextSize = 14 }, }, }, - beatmapTypeInfo = new BeatmapTypeInfo + new FillFlowContainer { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - }, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + beatmapTypeInfo = new BeatmapTypeInfo(), + modDisplay = new ModDisplay + { + Scale = new Vector2(0.75f), + DisplayUnrankedText = false + }, + } + } + }, }, readyButton = new ReadyButton @@ -95,6 +112,7 @@ namespace osu.Game.Screens.Multi.Match.Components beatmapTypeInfo.Beatmap.BindTo(Beatmap); beatmapTypeInfo.Type.BindTo(Type); + modDisplay.Current.BindTo(Mods); Availability.BindValueChanged(_ => updateAvailabilityStatus()); Status.BindValueChanged(_ => updateAvailabilityStatus()); diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 755b071f30..ecc5c91be3 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -9,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Select; using osu.Game.Users; @@ -33,6 +35,9 @@ namespace osu.Game.Screens.Multi.Match public override string ShortTitle => "room"; + [Cached] + private readonly Bindable> mods = new Bindable>(Enumerable.Empty()); + [Cached] private readonly Room room; @@ -101,6 +106,7 @@ namespace osu.Game.Screens.Multi.Match info.Status.BindTo(statusBind); info.Availability.BindTo(availabilityBind); info.Type.BindTo(typeBind); + info.Mods.BindTo(mods); participants.Users.BindTo(participantsBind); participants.MaxParticipants.BindTo(maxParticipantsBind); diff --git a/osu.Game/Screens/Play/HUD/ModDisplay.cs b/osu.Game/Screens/Play/HUD/ModDisplay.cs index 9509c7acae..7536501c90 100644 --- a/osu.Game/Screens/Play/HUD/ModDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModDisplay.cs @@ -20,6 +20,8 @@ namespace osu.Game.Screens.Play.HUD { private const int fade_duration = 1000; + public bool DisplayUnrankedText = true; + private readonly Bindable> mods = new Bindable>(); public Bindable> Current => mods; @@ -29,6 +31,8 @@ namespace osu.Game.Screens.Play.HUD public ModDisplay() { + AutoSizeAxes = Axes.Both; + Children = new Drawable[] { iconsContainer = new ReverseChildIDFillFlowContainer @@ -41,7 +45,6 @@ namespace osu.Game.Screens.Play.HUD }, unrankedText = new OsuSpriteText { - AlwaysPresent = true, Anchor = Anchor.BottomCentre, Origin = Anchor.TopCentre, Text = @"/ UNRANKED /", @@ -77,7 +80,7 @@ namespace osu.Game.Screens.Play.HUD private void appearTransform() { - if (mods.Value.Any(m => !m.Ranked)) + if (DisplayUnrankedText && mods.Value.Any(m => !m.Ranked)) unrankedText.FadeInFromZero(fade_duration, Easing.OutQuint); else unrankedText.Hide(); From 439d741dee62f95c67547afe116c858d1c28e484 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Dec 2018 16:06:56 +0900 Subject: [PATCH 040/220] Implement basic api structure for rooms --- osu.Game/Online/Multiplayer/Room.cs | 92 ++++++++++++++++++++++++++++- osu.Game/Rulesets/Mods/IMod.cs | 3 + 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 67ddb60823..71668e4c4b 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -3,16 +3,28 @@ using System.Collections.Generic; using System.Linq; +using Newtonsoft.Json; using osu.Framework.Configuration; using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Users; namespace osu.Game.Online.Multiplayer { public class Room { - public Bindable Name = new Bindable("My awesome room!"); - public Bindable Host = new Bindable(); + public Bindable RoomID { get; } = new Bindable(); + + [JsonProperty("name")] + public readonly Bindable Name = new Bindable("My awesome room!"); + + [JsonProperty("host")] + public readonly Bindable Host = new Bindable(); + + [JsonProperty("playlist")] + public readonly BindableCollection Playlist = new BindableCollection(); + public Bindable Status = new Bindable(new RoomStatusOpen()); public Bindable Availability = new Bindable(); public Bindable Type = new Bindable(new GameTypeTimeshift()); @@ -20,6 +32,82 @@ namespace osu.Game.Online.Multiplayer public Bindable MaxParticipants = new Bindable(); public Bindable> Participants = new Bindable>(Enumerable.Empty()); + public void CopyFrom(Room other) + { + Name.Value = other.Name; + Host.Value = other.Host; + Status.Value = other.Status; + Availability.Value = other.Availability; + Type.Value = other.Type; + Beatmap.Value = other.Beatmap; + MaxParticipants.Value = other.MaxParticipants; + Participants.Value = other.Participants.Value.ToArray(); + } + public Bindable Created = new Bindable(); } + + public class PlaylistItem + { + [JsonProperty("beatmap")] + public BeatmapInfo Beatmap; + + [JsonProperty("ruleset_id")] + public int RulesetID { get; set; } + + public readonly BindableCollection AllowedMods = new BindableCollection(); + + public readonly BindableCollection RequiredMods = new BindableCollection(); + + private APIMod[] _allowedMods; + + [JsonProperty("allowed_mods")] + private APIMod[] allowedMods + { + get => AllowedMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray(); + set => _allowedMods = value; + } + + private APIMod[] _requiredMods; + + [JsonProperty("required_mods")] + private APIMod[] requiredMods + { + get => RequiredMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray(); + set => _requiredMods = value; + } + + private RulesetInfo ruleset; + + public RulesetInfo Ruleset + { + get => ruleset; + set + { + ruleset = value; + + if (_allowedMods != null) + { + AllowedMods.Clear(); + AllowedMods.AddRange(value.CreateInstance().GetAllMods().Where(mod => _allowedMods.Any(m => m.Acronym == mod.Acronym))); + + _allowedMods = null; + } + + if (_requiredMods != null) + { + RequiredMods.Clear(); + RequiredMods.AddRange(value.CreateInstance().GetAllMods().Where(mod => _requiredMods.Any(m => m.Acronym == mod.Acronym))); + + _requiredMods = null; + } + } + } + + // Todo: Move this elsewhere for reusability + private class APIMod : IMod + { + public string Acronym { get; set; } + } + } } diff --git a/osu.Game/Rulesets/Mods/IMod.cs b/osu.Game/Rulesets/Mods/IMod.cs index d0c4ce2f4c..4a95ce8111 100644 --- a/osu.Game/Rulesets/Mods/IMod.cs +++ b/osu.Game/Rulesets/Mods/IMod.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using Newtonsoft.Json; + namespace osu.Game.Rulesets.Mods { public interface IMod @@ -8,6 +10,7 @@ namespace osu.Game.Rulesets.Mods /// /// The shortened name of this mod. /// + [JsonProperty] string Acronym { get; } } } From 6123a11b67b6425606d45889807f9fdecdf83c1c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Dec 2018 16:20:11 +0900 Subject: [PATCH 041/220] Use RoomID for creation --- osu.Game/Online/Multiplayer/Room.cs | 5 ++--- osu.Game/Screens/Multi/Match/Components/Header.cs | 6 +++--- .../Screens/Multi/Match/Components/MatchTabControl.cs | 8 ++++---- osu.Game/Screens/Multi/RoomManager.cs | 1 - 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 71668e4c4b..6dae9d2d74 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -14,7 +14,7 @@ namespace osu.Game.Online.Multiplayer { public class Room { - public Bindable RoomID { get; } = new Bindable(); + public Bindable RoomID { get; } = new Bindable(); [JsonProperty("name")] public readonly Bindable Name = new Bindable("My awesome room!"); @@ -34,6 +34,7 @@ namespace osu.Game.Online.Multiplayer public void CopyFrom(Room other) { + RoomID.Value = other.RoomID; Name.Value = other.Name; Host.Value = other.Host; Status.Value = other.Status; @@ -43,8 +44,6 @@ namespace osu.Game.Online.Multiplayer MaxParticipants.Value = other.MaxParticipants; Participants.Value = other.Participants.Value.ToArray(); } - - public Bindable Created = new Bindable(); } public class PlaylistItem diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 9c72403806..b5ae3baa15 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Multi.Match.Components private class BeatmapSelectButton : TriangleButton { - private readonly IBindable createdBind = new Bindable(); + private readonly IBindable roomIDBind = new Bindable(); [Resolved] private Room room { get; set; } @@ -113,8 +113,8 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load() { - createdBind.BindTo(room.Created); - createdBind.BindValueChanged(v => Enabled.Value = !v, true); + roomIDBind.BindTo(room.RoomID); + roomIDBind.BindValueChanged(v => Enabled.Value = !v.HasValue, true); } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs b/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs index 51698fa50f..fa760c97e3 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Multi.Match.Components { public class MatchTabControl : PageTabControl { - private readonly IBindable created = new Bindable(); + private readonly IBindable roomIdBind = new Bindable(); [Resolved] private Room room { get; set; } @@ -28,10 +28,10 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load() { - created.BindTo(room.Created); - created.BindValueChanged(v => + roomIdBind.BindTo(room.RoomID); + roomIdBind.BindValueChanged(v => { - if (v) + if (v.HasValue) { Items.ForEach(t => t.Enabled.Value = !(t is SettingsMatchPage)); Current.Value = new RoomMatchPage(); diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 9e233f278b..e2d132b8bb 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -25,7 +25,6 @@ namespace osu.Game.Screens.Multi // Todo: Perform API request - room.Created.Value = true; rooms.Add(room); } } From 87ebb00f1c5787a0a1629eac9b0a5c8f48d4a035 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Dec 2018 19:03:27 +0900 Subject: [PATCH 042/220] Make Target abstract (should absolutely always be set) --- osu.Game/Online/API/APIRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index adbedb2aac..baa5ab3267 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -40,7 +40,7 @@ namespace osu.Game.Online.API /// public int Timeout = WebRequest.DEFAULT_TIMEOUT; - protected virtual string Target => string.Empty; + protected abstract string Target { get; } protected virtual WebRequest CreateWebRequest() => new WebRequest(Uri); From 450e4cd2235a6250245f9336f9c22ec16eca7982 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Dec 2018 19:04:11 +0900 Subject: [PATCH 043/220] Hook up API --- osu.Game.Tests/Visual/TestCaseDrawableRoom.cs | 135 ------------ osu.Game.Tests/Visual/TestCaseLounge.cs | 208 ------------------ osu.Game.Tests/Visual/TestCaseMatch.cs | 152 ------------- .../Visual/TestCaseRoomInspector.cs | 141 ------------ osu.Game/Online/Multiplayer/Room.cs | 45 +++- osu.Game/Overlays/Music/PlaylistItem.cs | 1 + osu.Game/Screens/Multi/RoomManager.cs | 105 ++++++++- 7 files changed, 144 insertions(+), 643 deletions(-) delete mode 100644 osu.Game.Tests/Visual/TestCaseDrawableRoom.cs delete mode 100644 osu.Game.Tests/Visual/TestCaseLounge.cs delete mode 100644 osu.Game.Tests/Visual/TestCaseMatch.cs delete mode 100644 osu.Game.Tests/Visual/TestCaseRoomInspector.cs diff --git a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs deleted file mode 100644 index bcebf0a8d9..0000000000 --- a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using NUnit.Framework; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Beatmaps; -using osu.Game.Graphics.UserInterface; -using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets; -using osu.Game.Screens.Multi.Lounge.Components; -using osu.Game.Users; - -namespace osu.Game.Tests.Visual -{ - [TestFixture] - public class TestCaseDrawableRoom : OsuTestCase - { - private RulesetStore rulesets; - - protected override void LoadComplete() - { - base.LoadComplete(); - - DrawableRoom first; - Add(new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Y, - Width = 580f, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - first = new DrawableRoom(new Room - { - Name = { Value = @"Great Room Right Here" }, - Host = { Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" } } }, - Status = { Value = new RoomStatusOpen() }, - Type = { Value = new GameTypeTeamVersus() }, - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 4.65, - Ruleset = rulesets.GetRuleset(3), - Metadata = new BeatmapMetadata - { - Title = @"Critical Crystal", - Artist = @"Seiryu", - }, - BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh//beatmaps/376340/covers/cover.jpg?1456478455", - }, - }, - }, - }, - }, - Participants = - { - Value = new[] - { - new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 1355 } } }, - new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 8756 } } }, - }, - }, - }), - new DrawableRoom(new Room - { - Name = { Value = @"Relax It's The Weekend" }, - Host = { Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" } } }, - Status = { Value = new RoomStatusPlaying() }, - Type = { Value = new GameTypeTagTeam() }, - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 1.96, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata - { - Title = @"Serendipity", - Artist = @"ZAQ", - }, - BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh//beatmaps/526839/covers/cover.jpg?1493815706", - }, - }, - }, - }, - }, - Participants = - { - Value = new[] - { - new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 578975 } } }, - new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24554 } } }, - }, - }, - }), - } - }); - - AddStep(@"select", () => first.State = SelectionState.Selected); - AddStep(@"change title", () => first.Room.Name.Value = @"I Changed Name"); - AddStep(@"change host", () => first.Room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } }); - AddStep(@"change status", () => first.Room.Status.Value = new RoomStatusPlaying()); - AddStep(@"change type", () => first.Room.Type.Value = new GameTypeVersus()); - AddStep(@"change beatmap", () => first.Room.Beatmap.Value = null); - AddStep(@"change participants", () => first.Room.Participants.Value = new[] - { - new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 1254 } } }, - new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 123189 } } }, - }); - AddStep(@"deselect", () => first.State = SelectionState.NotSelected); - } - - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) - { - this.rulesets = rulesets; - } - } -} diff --git a/osu.Game.Tests/Visual/TestCaseLounge.cs b/osu.Game.Tests/Visual/TestCaseLounge.cs deleted file mode 100644 index c1253e4f5c..0000000000 --- a/osu.Game.Tests/Visual/TestCaseLounge.cs +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using NUnit.Framework; -using osu.Framework.Allocation; -using osu.Game.Beatmaps; -using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets; -using osu.Game.Screens; -using osu.Game.Screens.Backgrounds; -using osu.Game.Screens.Multi; -using osu.Game.Screens.Multi.Lounge; -using osu.Game.Screens.Multi.Lounge.Components; -using osu.Game.Users; -using osuTK.Input; - -namespace osu.Game.Tests.Visual -{ - [TestFixture] - public class TestCaseLounge : ManualInputManagerTestCase - { - private TestLoungeScreen loungeScreen; - - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) - { - loungeScreen = new TestLoungeScreen(); - - Room[] rooms = - { - new Room - { - Name = { Value = @"Just Another Room" }, - Host = { Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } } }, - Status = { Value = new RoomStatusPlaying() }, - Availability = { Value = RoomAvailability.Public }, - Type = { Value = new GameTypeTagTeam() }, - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 5.65, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata - { - Title = @"Sidetracked Day (Short Ver.)", - Artist = @"VINXIS", - AuthorString = @"Hobbes2", - }, - BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/767600/covers/cover.jpg?1526243446", - }, - }, - }, - } - }, - MaxParticipants = { Value = 10 }, - Participants = - { - Value = new[] - { - new User { Username = @"flyte", Id = 3103765, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 142 } } }, - new User { Username = @"Cookiezi", Id = 124493, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 546 } } }, - new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 287 } } }, - new User { Username = @"Rafis", Id = 2558286, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 468 } } }, - new User { Username = @"hvick225", Id = 50265, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 325 } } }, - new User { Username = @"peppy", Id = 2, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 625 } } }, - } - } - }, - new Room - { - Name = { Value = @"Not Just Any Room" }, - Host = { Value = new User { Username = @"Monstrata", Id = 2706438, Country = new Country { FlagName = @"CA" } } }, - Status = { Value = new RoomStatusOpen() }, - Availability = { Value = RoomAvailability.FriendsOnly }, - Type = { Value = new GameTypeTeamVersus() }, - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 2.73, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata - { - Title = @"lit(var)", - Artist = @"kensuke ushio", - AuthorString = @"Monstrata", - }, - BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/623972/covers/cover.jpg?1521167183", - }, - }, - }, - } - }, - Participants = - { - Value = new[] - { - new User { Username = @"Jeby", Id = 3136279, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 3497 } } }, - new User { Username = @"DualAkira", Id = 5220933, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 643 } } }, - new User { Username = @"Datenshi Yohane", Id = 7171857, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 10555 } } }, - } - } - }, - new Room - { - Name = { Value = @"room THE FINAL" }, - Host = { Value = new User { Username = @"Delis", Id = 1603923, Country = new Country { FlagName = @"JP" } } }, - Status = { Value = new RoomStatusPlaying() }, - Availability = { Value = RoomAvailability.Public }, - Type = { Value = new GameTypeTagTeam() }, - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 4.48, - Ruleset = rulesets.GetRuleset(3), - Metadata = new BeatmapMetadata - { - Title = @"ONIGIRI FREEWAY", - Artist = @"OISHII", - AuthorString = @"Mentholzzz", - }, - BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/663098/covers/cover.jpg?1521898837", - }, - }, - }, - } - }, - MaxParticipants = { Value = 30 }, - Participants = - { - Value = new[] - { - new User { Username = @"KizuA", Id = 6510442, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 5372 } } }, - new User { Username = @"Colored", Id = 827563, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 810 } } }, - new User { Username = @"Beryl", Id = 3817591, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 10096 } } }, - } - } - }, - }; - - AddStep(@"show", () => Add(loungeScreen)); - selectAssert(0); - AddAssert(@"no room selected", () => loungeScreen.SelectedRoom == null); - selectAssert(1); - AddStep(@"open room 1", () => clickRoom(1)); - AddUntilStep(() => loungeScreen.ChildScreen?.IsCurrentScreen == true, "wait until room current"); - AddStep(@"make lounge current", loungeScreen.MakeCurrent); - filterAssert(@"THE FINAL", LoungeTab.Public, 1); - filterAssert(string.Empty, LoungeTab.Public, 2); - filterAssert(string.Empty, LoungeTab.Private, 1); - filterAssert(string.Empty, LoungeTab.Public, 2); - filterAssert(@"no matches", LoungeTab.Public, 0); - filterAssert(string.Empty, LoungeTab.Public, 2); - AddStep(@"exit", loungeScreen.Exit); - } - - private void clickRoom(int n) - { - InputManager.Click(MouseButton.Left); - } - - private void selectAssert(int n) - { - AddStep($@"select room {n}", () => clickRoom(n)); - } - - private void filterAssert(string filter, LoungeTab tab, int endCount) - { - AddStep($@"filter '{filter}', {tab}", () => loungeScreen.SetFilter(filter, tab)); - } - - private class TestLoungeScreen : LoungeScreen - { - protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault(); - - [Resolved] - private RoomManager manager { get; set; } - - public Room SelectedRoom => manager.Current.Value; - - public void SetFilter(string filter, LoungeTab tab) - { - Filter.Search.Current.Value = filter; - Filter.Tabs.Current.Value = tab; - } - } - } -} diff --git a/osu.Game.Tests/Visual/TestCaseMatch.cs b/osu.Game.Tests/Visual/TestCaseMatch.cs deleted file mode 100644 index fd4806ac90..0000000000 --- a/osu.Game.Tests/Visual/TestCaseMatch.cs +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using NUnit.Framework; -using osu.Framework.Allocation; -using osu.Game.Beatmaps; -using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets; -using osu.Game.Screens.Multi.Match; -using osu.Game.Screens.Multi.Match.Components; -using osu.Game.Users; - -namespace osu.Game.Tests.Visual -{ - [TestFixture] - public class TestCaseMatch : OsuTestCase - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(TestCaseMatch), - typeof(GameTypePicker), - typeof(RoomSettingsOverlay) - }; - - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) - { - Room room = new Room - { - Name = { Value = @"One Awesome Room" }, - Status = { Value = new RoomStatusOpen() }, - Availability = { Value = RoomAvailability.Public }, - Type = { Value = new GameTypeTeamVersus() }, - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 5.02, - Ruleset = rulesets.GetRuleset(1), - Metadata = new BeatmapMetadata - { - Title = @"Paradigm Shift", - Artist = @"Morimori Atsushi", - AuthorString = @"eiri-", - }, - BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/765055/covers/cover.jpg?1526955337", - }, - }, - }, - }, - }, - MaxParticipants = { Value = 5 }, - Participants = - { - Value = new[] - { - new User - { - Username = @"eiri-", - Id = 3388410, - Country = new Country { FlagName = @"US" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/3388410/00a8486a247831e1cc4375db519f611ac970bda8bc0057d78b0f540ea38c3e58.jpeg", - IsSupporter = true, - }, - new User - { - Username = @"Nepuri", - Id = 6637817, - Country = new Country { FlagName = @"DE" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/6637817/9085fc60248b6b5327a72c1dcdecf2dbedba810ae0ab6bcf7224e46b1339632a.jpeg", - IsSupporter = true, - }, - new User - { - Username = @"goheegy", - Id = 8057655, - Country = new Country { FlagName = @"GB" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/8057655/21cec27c25a11dc197a4ec6a74253dbabb495949b0e0697113352f12007018c5.jpeg", - }, - new User - { - Username = @"Alumetri", - Id = 5371497, - Country = new Country { FlagName = @"RU" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/5371497/e023b8c7fbe3613e64bd4856703517ea50fbed8a5805dc9acda9efe9897c67e2.jpeg", - }, - } - }, - }; - - MatchScreen matchScreen = new MatchScreen(room); - - AddStep(@"show", () => Add(matchScreen)); - AddStep(@"null beatmap", () => room.Beatmap.Value = null); - AddStep(@"change name", () => room.Name.Value = @"Two Awesome Rooms"); - AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying()); - AddStep(@"change availability", () => room.Availability.Value = RoomAvailability.FriendsOnly); - AddStep(@"change type", () => room.Type.Value = new GameTypeTag()); - AddStep(@"change beatmap", () => room.Beatmap.Value = new BeatmapInfo - { - StarDifficulty = 4.33, - Ruleset = rulesets.GetRuleset(2), - Metadata = new BeatmapMetadata - { - Title = @"Yasashisa no Riyuu", - Artist = @"ChouCho", - AuthorString = @"celerih", - }, - BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/685391/covers/cover.jpg?1524597970", - }, - }, - }, - }); - - AddStep(@"null max participants", () => room.MaxParticipants.Value = null); - AddStep(@"change participants", () => room.Participants.Value = new[] - { - new User - { - Username = @"Spectator", - Id = 702598, - Country = new Country { FlagName = @"KR" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/702598/3bbf4cb8b8d2cf8b03145000a975ff27e191ab99b0920832e7dd67386280e288.jpeg", - IsSupporter = true, - }, - new User - { - Username = @"celerih", - Id = 4696296, - Country = new Country { FlagName = @"CA" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/4696296/7f8500731d0ac66d5472569d146a7be07d9460273361913f22c038867baddaef.jpeg", - }, - }); - - AddStep(@"exit", matchScreen.Exit); - } - } -} diff --git a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs deleted file mode 100644 index 9f6eea68e7..0000000000 --- a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using NUnit.Framework; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Game.Beatmaps; -using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets; -using osu.Game.Screens.Multi.Lounge.Components; -using osu.Game.Users; - -namespace osu.Game.Tests.Visual -{ - [TestFixture] - public class TestCaseRoomInspector : OsuTestCase - { - private RulesetStore rulesets; - - protected override void LoadComplete() - { - base.LoadComplete(); - - Room room = new Room - { - Name = { Value = @"My Awesome Room" }, - Host = { Value = new User { Username = @"flyte", Id = 3103765, Country = new Country { FlagName = @"JP" } } }, - Status = { Value = new RoomStatusOpen() }, - Type = { Value = new GameTypeTeamVersus() }, - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 3.7, - Ruleset = rulesets.GetRuleset(3), - Metadata = new BeatmapMetadata - { - Title = @"Platina", - Artist = @"Maaya Sakamoto", - AuthorString = @"uwutm8", - }, - BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/560573/covers/cover.jpg?1492722343", - }, - }, - }, - } - }, - MaxParticipants = { Value = 200 }, - Participants = - { - Value = new[] - { - new User { Username = @"flyte", Id = 3103765, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 142 } } }, - new User { Username = @"Cookiezi", Id = 124493, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 546 } } }, - new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 287 } } }, - new User { Username = @"Rafis", Id = 2558286, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 468 } } }, - new User { Username = @"hvick225", Id = 50265, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 325 } } }, - new User { Username = @"peppy", Id = 2, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 625 } } }, - } - } - }; - - Add(new RoomInspector - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Width = 0.5f, - }); - - AddStep(@"change title", () => room.Name.Value = @"A Better Room Than The Above"); - AddStep(@"change host", () => room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } }); - AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying()); - AddStep(@"change type", () => room.Type.Value = new GameTypeTag()); - AddStep(@"change beatmap", () => room.Beatmap.Value = null); - AddStep(@"change max participants", () => room.MaxParticipants.Value = null); - AddStep(@"change participants", () => room.Participants.Value = new[] - { - new User { Username = @"filsdelama", Id = 2831793, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 854 } } }, - new User { Username = @"_index", Id = 652457, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 150 } } } - }); - - AddStep(@"change room", () => - { - Room newRoom = new Room - { - Name = { Value = @"My New, Better Than Ever Room" }, - Host = { Value = new User { Username = @"Angelsim", Id = 1777162, Country = new Country { FlagName = @"KR" } } }, - Status = { Value = new RoomStatusOpen() }, - Type = { Value = new GameTypeTagTeam() }, - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 7.07, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata - { - Title = @"FREEDOM DIVE", - Artist = @"xi", - AuthorString = @"Nakagawa-Kanon", - }, - BeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/39804/covers/cover.jpg?1456506845", - }, - }, - }, - }, - }, - MaxParticipants = { Value = 10 }, - Participants = - { - Value = new[] - { - new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 4 } } }, - new User { Username = @"HappyStick", Id = 256802, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 752 } } }, - new User { Username = @"-Konpaku-", Id = 2258797, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 571 } } } - } - } - }; - }); - } - - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) - { - this.rulesets = rulesets; - } - } -} diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 6dae9d2d74..56c4585b2a 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -6,6 +6,7 @@ using System.Linq; using Newtonsoft.Json; using osu.Framework.Configuration; using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Users; @@ -14,24 +15,44 @@ namespace osu.Game.Online.Multiplayer { public class Room { + [JsonProperty("id")] public Bindable RoomID { get; } = new Bindable(); + [JsonIgnore] + public readonly Bindable Beatmap = new Bindable(); + [JsonProperty("name")] public readonly Bindable Name = new Bindable("My awesome room!"); [JsonProperty("host")] public readonly Bindable Host = new Bindable(); + public bool ShouldSerializeHost() => false; + [JsonProperty("playlist")] public readonly BindableCollection Playlist = new BindableCollection(); + [JsonProperty("duration")] + public readonly Bindable Duration = new Bindable(100); + + [JsonProperty("max_attempts")] + public readonly Bindable MaxAttempts = new Bindable(null); + public Bindable Status = new Bindable(new RoomStatusOpen()); public Bindable Availability = new Bindable(); public Bindable Type = new Bindable(new GameTypeTimeshift()); - public Bindable Beatmap = new Bindable(); public Bindable MaxParticipants = new Bindable(); public Bindable> Participants = new Bindable>(Enumerable.Empty()); + public Room() + { + Beatmap.BindValueChanged(b => + { + Playlist.Clear(); + Playlist.Add(new PlaylistItem { Beatmap = b }); + }); + } + public void CopyFrom(Room other) { RoomID.Value = other.RoomID; @@ -40,22 +61,34 @@ namespace osu.Game.Online.Multiplayer Status.Value = other.Status; Availability.Value = other.Availability; Type.Value = other.Type; - Beatmap.Value = other.Beatmap; MaxParticipants.Value = other.MaxParticipants; Participants.Value = other.Participants.Value.ToArray(); + + // Temp: + Beatmap.Value = Playlist.FirstOrDefault()?.Beatmap; } } public class PlaylistItem { [JsonProperty("beatmap")] - public BeatmapInfo Beatmap; + private APIBeatmap beatmap { get; set; } + + public bool ShouldSerializebeatmap() => false; + + [JsonIgnore] + public BeatmapInfo Beatmap { get; set; } + + [JsonProperty("beatmap_id")] + public int BeatmapID => 847296; //Beatmap.OnlineBeatmapID ?? 0; [JsonProperty("ruleset_id")] public int RulesetID { get; set; } + [JsonIgnore] public readonly BindableCollection AllowedMods = new BindableCollection(); + [JsonIgnore] public readonly BindableCollection RequiredMods = new BindableCollection(); private APIMod[] _allowedMods; @@ -78,6 +111,7 @@ namespace osu.Game.Online.Multiplayer private RulesetInfo ruleset; + [JsonIgnore] public RulesetInfo Ruleset { get => ruleset; @@ -103,6 +137,11 @@ namespace osu.Game.Online.Multiplayer } } + public void SetRulesets(RulesetStore rulesets) + { + Beatmap = beatmap.ToBeatmap(rulesets); + } + // Todo: Move this elsewhere for reusability private class APIMod : IMod { diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index b4828e41f6..9368bee81c 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -8,6 +8,7 @@ using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Beatmaps; diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index e2d132b8bb..fead90f9a2 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -1,15 +1,24 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Newtonsoft.Json; using osu.Framework.Allocation; using osu.Framework.Configuration; -using osu.Framework.Graphics; +using osu.Framework.IO.Network; +using osu.Framework.Logging; +using osu.Game.Beatmaps; +using osu.Game.Online; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; namespace osu.Game.Screens.Multi { - public class RoomManager : Component + public class RoomManager : PollingComponent { public IBindableCollection Rooms => rooms; private readonly BindableCollection rooms = new BindableCollection(); @@ -19,13 +28,101 @@ namespace osu.Game.Screens.Multi [Resolved] private APIAccess api { get; set; } + [Resolved] + private RulesetStore rulesets { get; set; } + + [Resolved] + private BeatmapManager beatmaps { get; set; } + + public RoomManager() + { + TimeBetweenPolls = 5000; + } + public void CreateRoom(Room room) { room.Host.Value = api.LocalUser; - // Todo: Perform API request + var req = new CreateRoomRequest(room); - rooms.Add(room); + req.Success += result => addRoom(room, result); + req.Failure += exception => Logger.Log($"Failed to create room: {exception}"); + api.Queue(req); + } + + protected override Task Poll() + { + if (!api.IsLoggedIn) + return base.Poll(); + + var tcs = new TaskCompletionSource(); + + var pollReq = new GetRoomsRequest(); + + pollReq.Success += result => + { + foreach (var r in result) + { + foreach (var pi in r.Playlist) + { + pi.Ruleset = rulesets.GetRuleset(pi.RulesetID); + pi.SetRulesets(rulesets); + } + + var existing = rooms.FirstOrDefault(e => e.RoomID.Value == r.RoomID.Value); + if (existing == null) + rooms.Add(r); + else + existing.CopyFrom(r); + } + + tcs.SetResult(true); + }; + + pollReq.Failure += _ => tcs.SetResult(false); + + api.Queue(pollReq); + + return tcs.Task; + } + + private void addRoom(Room local, Room remote) + { + local.CopyFrom(remote); + + var existing = rooms.FirstOrDefault(e => e.RoomID.Value == local.RoomID.Value); + if (existing != null) + rooms.Remove(existing); + rooms.Add(local); + } + + private class CreateRoomRequest : APIRequest + { + private readonly Room room; + + public CreateRoomRequest(Room room) + { + this.room = room; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + + req.ContentType = "application/json"; + req.Method = HttpMethod.Post; + + req.AddRaw(JsonConvert.SerializeObject(room)); + + return req; + } + + protected override string Target => "rooms"; + } + + private class GetRoomsRequest : APIRequest> + { + protected override string Target => "rooms"; } } } From bac4f42eac5015c9b20edc22933138fcf4b95f03 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Dec 2018 19:34:37 +0900 Subject: [PATCH 044/220] Fix backgrounds not quite working --- .../UpdateableBeatmapBackgroundSprite.cs | 17 ++++++++++++----- .../Online/API/Requests/Responses/APIBeatmap.cs | 6 +----- osu.Game/Online/Multiplayer/Room.cs | 3 --- .../Multi/Lounge/Components/DrawableRoom.cs | 3 +-- .../Multi/Lounge/Components/RoomInspector.cs | 2 +- .../Screens/Multi/Match/Components/Header.cs | 2 +- osu.Game/Screens/Multi/Match/MatchScreen.cs | 2 +- osu.Game/Screens/Multi/RoomManager.cs | 3 +++ 8 files changed, 20 insertions(+), 18 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 5ced21e436..0a9726b121 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -9,21 +9,28 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Beatmaps.Drawables { - public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable + public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable { - public readonly IBindable Beatmap = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); [Resolved] - private OsuGameBase game { get; set; } + private BeatmapManager beatmaps { get; set; } public UpdateableBeatmapBackgroundSprite() { Beatmap.BindValueChanged(b => Schedule(() => Model = b)); } - protected override Drawable CreateDrawable(WorkingBeatmap model) + protected override Drawable CreateDrawable(BeatmapInfo model) { - Drawable drawable = model == null ? (Drawable)new DefaultSprite() : new BeatmapBackgroundSprite(model); + Drawable drawable; + + if (model == null) + drawable = new DefaultSprite(); + else if (model.BeatmapSet?.OnlineInfo != null) + drawable = new BeatmapSetCover(model.BeatmapSet); + else + drawable = new BeatmapBackgroundSprite(beatmaps.GetWorkingBeatmap(model)); drawable.RelativeSizeAxes = Axes.Both; drawable.Anchor = Anchor.Centre; diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 193ccf1f6b..b96e4bedf6 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -67,11 +67,7 @@ namespace osu.Game.Online.API.Requests.Responses OnlineBeatmapID = OnlineBeatmapID, Version = version, Status = Status, - BeatmapSet = new BeatmapSetInfo - { - OnlineBeatmapSetID = OnlineBeatmapSetID, - Status = BeatmapSet?.Status ?? BeatmapSetOnlineStatus.None - }, + BeatmapSet = BeatmapSet.ToBeatmapSet(rulesets), BaseDifficulty = new BeatmapDifficulty { DrainRate = drainRate, diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 56c4585b2a..4af92f68ea 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -63,9 +63,6 @@ namespace osu.Game.Online.Multiplayer Type.Value = other.Type; MaxParticipants.Value = other.MaxParticipants; Participants.Value = other.Participants.Value.ToArray(); - - // Temp: - Beatmap.Value = Playlist.FirstOrDefault()?.Beatmap; } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index 57ce9fc0b9..647913308d 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -213,8 +213,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components d.FadeColour(s.GetAppropriateColour(colours), transition_duration); }; - background.Beatmap.BindTo(beatmap); - beatmapBind.BindValueChanged(b => beatmap.Value = beatmaps.GetWorkingBeatmap(b)); nameBind.BindValueChanged(n => name.Text = n); @@ -224,6 +222,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components typeBind.BindTo(Room.Type); beatmapBind.BindTo(Room.Beatmap); participantsBind.BindTo(Room.Participants); + background.Beatmap.BindTo(beatmapBind); modeTypeInfo.Beatmap.BindTo(beatmapBind); modeTypeInfo.Type.BindTo(typeBind); diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index e8de201b8f..5b796b5a3d 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -180,7 +180,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components nameBind.BindValueChanged(n => name.Text = n); - background.Beatmap.BindTo(beatmap); + background.Beatmap.BindTo(beatmapBind); participantInfo.Host.BindTo(hostBind); participantInfo.Participants.BindTo(participantsBind); diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index b5ae3baa15..005378756e 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Multi.Match.Components { public const float HEIGHT = 200; - public readonly IBindable Beatmap = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); private readonly Box tabStrip; diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 755b071f30..a2a7c4e70d 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Multi.Match }; header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect()); - header.Beatmap.BindTo(Beatmap); + header.Beatmap.BindTo(beatmapBind); header.Tabs.Current.ValueChanged += t => { diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index fead90f9a2..d6c5a12d33 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -69,6 +69,9 @@ namespace osu.Game.Screens.Multi pi.SetRulesets(rulesets); } + // Temporarily + r.Beatmap.Value = r.Playlist.FirstOrDefault()?.Beatmap; + var existing = rooms.FirstOrDefault(e => e.RoomID.Value == r.RoomID.Value); if (existing == null) rooms.Add(r); From 264bd0e2aafd1283c1d7e45f5d8c5f0018260dc1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Dec 2018 16:06:30 +0900 Subject: [PATCH 045/220] Fix invalid room values --- osu.Game/Online/Multiplayer/Room.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 4af92f68ea..e2322db397 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -35,8 +35,16 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("duration")] public readonly Bindable Duration = new Bindable(100); - [JsonProperty("max_attempts")] - public readonly Bindable MaxAttempts = new Bindable(null); + [JsonIgnore] + public readonly Bindable MaxAttempts = new Bindable(); + + // Todo: Find a better way to do this (https://github.com/ppy/osu-framework/issues/1930) + [JsonProperty("max_attempts", DefaultValueHandling = DefaultValueHandling.Ignore)] + private int? maxAttempts + { + get => MaxAttempts; + set => MaxAttempts.Value = value; + } public Bindable Status = new Bindable(new RoomStatusOpen()); public Bindable Availability = new Bindable(); From 680a3e2aa4ad88e875b3843d290aceaa0c44bbec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Dec 2018 18:38:03 +0900 Subject: [PATCH 046/220] Update with proper playlist usage --- .../UpdateableBeatmapBackgroundSprite.cs | 2 +- osu.Game/Online/Multiplayer/Room.cs | 12 ----- .../Multi/Lounge/Components/DrawableRoom.cs | 32 ++++++++---- .../Multi/Lounge/Components/RoomInspector.cs | 23 +++++--- .../Screens/Multi/Match/Components/Header.cs | 2 +- .../Match/Components/RoomSettingsOverlay.cs | 7 ++- osu.Game/Screens/Multi/Match/MatchScreen.cs | 52 +++++++++++++++---- osu.Game/Screens/Multi/RoomManager.cs | 3 -- 8 files changed, 87 insertions(+), 46 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 0a9726b121..15b89d27bd 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -11,7 +11,7 @@ namespace osu.Game.Beatmaps.Drawables { public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable { - public readonly IBindable Beatmap = new Bindable(); + public readonly Bindable Beatmap = new Bindable(); [Resolved] private BeatmapManager beatmaps { get; set; } diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index e2322db397..5e9fc4f008 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -18,9 +18,6 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("id")] public Bindable RoomID { get; } = new Bindable(); - [JsonIgnore] - public readonly Bindable Beatmap = new Bindable(); - [JsonProperty("name")] public readonly Bindable Name = new Bindable("My awesome room!"); @@ -52,15 +49,6 @@ namespace osu.Game.Online.Multiplayer public Bindable MaxParticipants = new Bindable(); public Bindable> Participants = new Bindable>(Enumerable.Empty()); - public Room() - { - Beatmap.BindValueChanged(b => - { - Playlist.Clear(); - Playlist.Add(new PlaylistItem { Beatmap = b }); - }); - } - public void CopyFrom(Room other) { RoomID.Value = other.RoomID; diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index 647913308d..c425f8ef0a 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Configuration; @@ -39,14 +40,18 @@ namespace osu.Game.Screens.Multi.Lounge.Components private readonly Box selectionBox; private readonly Bindable nameBind = new Bindable(); - private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable hostBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); + private readonly IBindableCollection playlistBind = new BindableCollection(); private readonly Bindable beatmap = new Bindable(); + private UpdateableBeatmapBackgroundSprite background; + private BeatmapTitle beatmapTitle; + private ModeTypeInfo modeTypeInfo; + [Resolved] private BeatmapManager beatmaps { get; set; } @@ -104,11 +109,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components private void load(OsuColour colours) { Box sideStrip; - UpdateableBeatmapBackgroundSprite background; OsuSpriteText status; ParticipantInfo participantInfo; - BeatmapTitle beatmapTitle; - ModeTypeInfo modeTypeInfo; + OsuSpriteText name; Children = new Drawable[] @@ -213,24 +216,24 @@ namespace osu.Game.Screens.Multi.Lounge.Components d.FadeColour(s.GetAppropriateColour(colours), transition_duration); }; - beatmapBind.BindValueChanged(b => beatmap.Value = beatmaps.GetWorkingBeatmap(b)); nameBind.BindValueChanged(n => name.Text = n); nameBind.BindTo(Room.Name); hostBind.BindTo(Room.Host); statusBind.BindTo(Room.Status); typeBind.BindTo(Room.Type); - beatmapBind.BindTo(Room.Beatmap); + playlistBind.BindTo(Room.Playlist); participantsBind.BindTo(Room.Participants); - background.Beatmap.BindTo(beatmapBind); - modeTypeInfo.Beatmap.BindTo(beatmapBind); modeTypeInfo.Type.BindTo(typeBind); participantInfo.Host.BindTo(hostBind); participantInfo.Participants.BindTo(participantsBind); - beatmapTitle.Beatmap.BindTo(beatmapBind); + playlistBind.ItemsAdded += _ => updatePlaylist(); + playlistBind.ItemsRemoved += _ => updatePlaylist(); + + updatePlaylist(); } protected override void LoadComplete() @@ -238,5 +241,16 @@ namespace osu.Game.Screens.Multi.Lounge.Components base.LoadComplete(); this.FadeInFromZero(transition_duration); } + + private void updatePlaylist() + { + // For now, only the first playlist item is supported + var item = playlistBind.First(); + + beatmap.Value = beatmaps.GetWorkingBeatmap(item.Beatmap); + background.Beatmap.Value = item.Beatmap; + modeTypeInfo.Beatmap.Value = item.Beatmap; + beatmapTitle.Beatmap.Value = item.Beatmap; + } } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 5b796b5a3d..1a2ff4c3d8 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -32,12 +32,12 @@ namespace osu.Game.Screens.Multi.Lounge.Components private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; private readonly Bindable nameBind = new Bindable(); - private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable hostBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); + private readonly IBindableCollection playlistBind = new BindableCollection(); private readonly Bindable beatmap = new Bindable(); @@ -174,14 +174,14 @@ namespace osu.Game.Screens.Multi.Lounge.Components }, }; + playlistBind.ItemsAdded += _ => updatePlaylist(); + playlistBind.ItemsRemoved += _ => updatePlaylist(); + statusBind.BindValueChanged(displayStatus); - beatmapBind.BindValueChanged(b => beatmap.Value = beatmaps.GetWorkingBeatmap(b)); participantsBind.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u))); nameBind.BindValueChanged(n => name.Text = n); - background.Beatmap.BindTo(beatmapBind); - participantInfo.Host.BindTo(hostBind); participantInfo.Participants.BindTo(participantsBind); @@ -189,7 +189,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components participantCount.MaxParticipants.BindTo(maxParticipantsBind); beatmapTypeInfo.Type.BindTo(typeBind); - beatmapTypeInfo.Beatmap.BindTo(beatmapBind); Room.BindValueChanged(updateRoom, true); } @@ -204,7 +203,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components hostBind.UnbindFrom(lastRoom.Host); statusBind.UnbindFrom(lastRoom.Status); typeBind.UnbindFrom(lastRoom.Type); - beatmapBind.UnbindFrom(lastRoom.Beatmap); + playlistBind.UnbindFrom(lastRoom.Playlist); maxParticipantsBind.UnbindFrom(lastRoom.MaxParticipants); participantsBind.UnbindFrom(lastRoom.Participants); } @@ -215,7 +214,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components hostBind.BindTo(newRoom.Host); statusBind.BindTo(newRoom.Status); typeBind.BindTo(newRoom.Type); - beatmapBind.BindTo(newRoom.Beatmap); + playlistBind.BindTo(newRoom.Playlist); maxParticipantsBind.BindTo(newRoom.MaxParticipants); participantsBind.BindTo(newRoom.Participants); @@ -239,6 +238,16 @@ namespace osu.Game.Screens.Multi.Lounge.Components lastRoom = newRoom; } + private void updatePlaylist() + { + // For now, only the first playlist item is supported + var item = playlistBind.First(); + + beatmap.Value = beatmaps.GetWorkingBeatmap(item.Beatmap); + background.Beatmap.Value = item.Beatmap; + beatmapTypeInfo.Beatmap.Value = item.Beatmap; + } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 005378756e..4e3349056c 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Multi.Match.Components { public const float HEIGHT = 200; - public readonly IBindable Beatmap = new Bindable(); + public readonly Bindable Beatmap = new Bindable(); private readonly Box tabStrip; diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index e4eb2046b2..d6098674c1 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -6,7 +6,6 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -23,10 +22,10 @@ namespace osu.Game.Screens.Multi.Match.Components private const float field_padding = 45; private readonly Bindable nameBind = new Bindable(); - private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable availabilityBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); + private readonly IBindableCollection playlistBind = new BindableCollection(); private readonly Container content; @@ -160,7 +159,7 @@ namespace osu.Game.Screens.Multi.Match.Components typeLabel.Colour = colours.Yellow; nameBind.BindTo(room.Name); - beatmapBind.BindTo(room.Beatmap); + playlistBind.BindTo(room.Playlist); availabilityBind.BindTo(room.Availability); typeBind.BindTo(room.Type); maxParticipantsBind.BindTo(room.MaxParticipants); @@ -179,7 +178,7 @@ namespace osu.Game.Screens.Multi.Match.Components ApplyButton.Enabled.Value = hasValidSettings; } - private bool hasValidSettings => NameField.Text.Length > 0 && beatmapBind.Value != null; + private bool hasValidSettings => NameField.Text.Length > 0 && playlistBind.Count > 0; protected override void PopIn() { diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index a2a7c4e70d..b4ff73bbe4 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -20,12 +21,12 @@ namespace osu.Game.Screens.Multi.Match private readonly Participants participants; private readonly Bindable nameBind = new Bindable(); - private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); private readonly Bindable availabilityBind = new Bindable(); private readonly Bindable typeBind = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); + private readonly BindableCollection playlistBind = new BindableCollection(); protected override Drawable TransitionContent => participants; @@ -33,6 +34,9 @@ namespace osu.Game.Screens.Multi.Match public override string ShortTitle => "room"; + private readonly Components.Header header; + private readonly Info info; + [Cached] private readonly Room room; @@ -47,16 +51,13 @@ namespace osu.Game.Screens.Multi.Match this.room = room; nameBind.BindTo(room.Name); - beatmapBind.BindTo(room.Beatmap); statusBind.BindTo(room.Status); availabilityBind.BindTo(room.Availability); typeBind.BindTo(room.Type); participantsBind.BindTo(room.Participants); maxParticipantsBind.BindTo(room.MaxParticipants); - Components.Header header; RoomSettingsOverlay settings; - Info info; Children = new Drawable[] { @@ -86,7 +87,6 @@ namespace osu.Game.Screens.Multi.Match }; header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect()); - header.Beatmap.BindTo(beatmapBind); header.Tabs.Current.ValueChanged += t => { @@ -96,7 +96,6 @@ namespace osu.Game.Screens.Multi.Match settings.Hide(); }; - info.Beatmap.BindTo(beatmapBind); info.Name.BindTo(nameBind); info.Status.BindTo(statusBind); info.Availability.BindTo(availabilityBind); @@ -104,14 +103,49 @@ namespace osu.Game.Screens.Multi.Match participants.Users.BindTo(participantsBind); participants.MaxParticipants.BindTo(maxParticipantsBind); + + playlistBind.ItemsAdded += _ => updatePlaylist(); + playlistBind.ItemsRemoved += _ => updatePlaylist(); } [BackgroundDependencyLoader] private void load() { - beatmapBind.BindTo(room.Beatmap); - beatmapBind.BindValueChanged(b => Beatmap.Value = beatmapManager.GetWorkingBeatmap(room.Beatmap.Value), true); - Beatmap.BindValueChanged(b => beatmapBind.Value = b.BeatmapInfo); + Beatmap.BindValueChanged(b => + { + playlistBind.Clear(); + + var newItem = new PlaylistItem + { + Beatmap = b.BeatmapInfo, + Ruleset = Ruleset.Value + }; + + newItem.RequiredMods.Clear(); + newItem.RequiredMods.AddRange(b.Mods.Value); + + playlistBind.Add(newItem); + }); + + playlistBind.BindTo(room.Playlist); + } + + private void updatePlaylist() + { + if (playlistBind.Count == 0) + return; + + // For now, only the first playlist item is supported + var item = playlistBind.First(); + + header.Beatmap.Value = item.Beatmap; + info.Beatmap.Value = item.Beatmap; + + if (Beatmap.Value?.BeatmapInfo != item.Beatmap) + { + Beatmap.Value = beatmapManager.GetWorkingBeatmap(item.Beatmap); + Beatmap.Value.Mods.Value = item.RequiredMods.ToArray(); + } } } } diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index d6c5a12d33..fead90f9a2 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -69,9 +69,6 @@ namespace osu.Game.Screens.Multi pi.SetRulesets(rulesets); } - // Temporarily - r.Beatmap.Value = r.Playlist.FirstOrDefault()?.Beatmap; - var existing = rooms.FirstOrDefault(e => e.RoomID.Value == r.RoomID.Value); if (existing == null) rooms.Add(r); From 8e6a85058b198e820e5fd2e4c5446a49583b0401 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 12:35:05 +0900 Subject: [PATCH 047/220] Fix playlist-related errors --- osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs | 3 +++ osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index c425f8ef0a..5cf11e5c98 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -244,6 +244,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components private void updatePlaylist() { + if (playlistBind.Count == 0) + return; + // For now, only the first playlist item is supported var item = playlistBind.First(); diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 1a2ff4c3d8..818fd78f32 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -240,6 +240,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components private void updatePlaylist() { + if (playlistBind.Count == 0) + return; + // For now, only the first playlist item is supported var item = playlistBind.First(); From 2e767a529253a6c99ec3d1c6a2dc50b07da21689 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 13:38:13 +0900 Subject: [PATCH 048/220] Fix incorrect acronym --- osu.Game/Rulesets/Mods/IMod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/IMod.cs b/osu.Game/Rulesets/Mods/IMod.cs index 4a95ce8111..49a3963496 100644 --- a/osu.Game/Rulesets/Mods/IMod.cs +++ b/osu.Game/Rulesets/Mods/IMod.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Mods /// /// The shortened name of this mod. /// - [JsonProperty] + [JsonProperty("acronym")] string Acronym { get; } } } From 56fd4b95cd9c69cb46f7e8277484e5fdf2559504 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 13:38:27 +0900 Subject: [PATCH 049/220] Fix mod/beatmap selection not always working --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 42 ++++++--------------- osu.Game/Screens/Select/MatchSongSelect.cs | 18 ++++++++- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index ca3f1eeb54..1d713dd0b1 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Play; using osu.Game.Screens.Play; @@ -40,9 +39,6 @@ namespace osu.Game.Screens.Multi.Match private readonly Components.Header header; private readonly Info info; - [Cached] - private readonly Bindable> mods = new Bindable>(Enumerable.Empty()); - [Cached] private readonly Room room; @@ -96,7 +92,7 @@ namespace osu.Game.Screens.Multi.Match }, }; - header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect()); + header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect { Selected = addPlaylistItem }); header.Tabs.Current.ValueChanged += t => { @@ -110,38 +106,27 @@ namespace osu.Game.Screens.Multi.Match info.Status.BindTo(statusBind); info.Availability.BindTo(availabilityBind); info.Type.BindTo(typeBind); - info.Mods.BindTo(mods); participants.Users.BindTo(participantsBind); participants.MaxParticipants.BindTo(maxParticipantsBind); - playlistBind.ItemsAdded += _ => updatePlaylist(); - playlistBind.ItemsRemoved += _ => updatePlaylist(); + playlistBind.ItemsAdded += _ => setFromPlaylist(); + playlistBind.ItemsRemoved += _ => setFromPlaylist(); } [BackgroundDependencyLoader] private void load() { - Beatmap.BindValueChanged(b => - { - playlistBind.Clear(); - - var newItem = new PlaylistItem - { - Beatmap = b.BeatmapInfo, - Ruleset = Ruleset.Value - }; - - newItem.RequiredMods.Clear(); - newItem.RequiredMods.AddRange(b.Mods.Value); - - playlistBind.Add(newItem); - }); - playlistBind.BindTo(room.Playlist); } - private void updatePlaylist() + private void addPlaylistItem(PlaylistItem item) + { + playlistBind.Clear(); + playlistBind.Add(item); + } + + private void setFromPlaylist() { if (playlistBind.Count == 0) return; @@ -151,12 +136,9 @@ namespace osu.Game.Screens.Multi.Match header.Beatmap.Value = item.Beatmap; info.Beatmap.Value = item.Beatmap; + info.Mods.Value = item.RequiredMods; - if (Beatmap.Value?.BeatmapInfo != item.Beatmap) - { - Beatmap.Value = beatmapManager.GetWorkingBeatmap(item.Beatmap); - Beatmap.Value.Mods.Value = item.RequiredMods.ToArray(); - } + Beatmap.Value = beatmapManager.GetWorkingBeatmap(item.Beatmap); } private void onStart() diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 94ac951159..10f29d929d 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -1,17 +1,33 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi; namespace osu.Game.Screens.Select { public class MatchSongSelect : SongSelect, IMultiplayerScreen { + public Action Selected; + public string ShortTitle => "song selection"; protected override bool OnStart() { - if (IsCurrentScreen) Exit(); + var item = new PlaylistItem + { + Beatmap = Beatmap.Value.BeatmapInfo, + Ruleset = Ruleset.Value, + }; + + item.RequiredMods.AddRange(SelectedMods.Value); + + Selected?.Invoke(item); + + if (IsCurrentScreen) + Exit(); + return true; } } From c9c04a6200bf51618d221de8b72f816edfb603e6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 13:43:52 +0900 Subject: [PATCH 050/220] Fix ToBeatmap not using the correct metadata Metadata is always come from the API via the beatmap set. --- osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index b96e4bedf6..2b4c69d332 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -59,15 +59,17 @@ namespace osu.Game.Online.API.Requests.Responses public BeatmapInfo ToBeatmap(RulesetStore rulesets) { + var set = BeatmapSet.ToBeatmapSet(rulesets); + return new BeatmapInfo { - Metadata = this, + Metadata = set.Metadata, Ruleset = rulesets.GetRuleset(ruleset), StarDifficulty = starDifficulty, OnlineBeatmapID = OnlineBeatmapID, Version = version, Status = Status, - BeatmapSet = BeatmapSet.ToBeatmapSet(rulesets), + BeatmapSet = set, BaseDifficulty = new BeatmapDifficulty { DrainRate = drainRate, From b83f99d90a88e2b1754098ee87c30142a7cee391 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 14:20:03 +0900 Subject: [PATCH 051/220] Fix up header sizing + styling --- osu.Game.Tests/Visual/TestCaseMatchInfo.cs | 10 ++++ .../Screens/Multi/Match/Components/Header.cs | 2 +- .../Multi/Match/Components/HeaderButton.cs | 48 +++++++++++++++++++ .../Screens/Multi/Match/Components/Info.cs | 43 +++++++++-------- .../Multi/Match/Components/ReadyButton.cs | 41 ++-------------- .../Match/Components/ViewBeatmapButton.cs | 19 ++++++++ osu.Game/Screens/Multi/Match/MatchScreen.cs | 24 +++++----- 7 files changed, 120 insertions(+), 67 deletions(-) create mode 100644 osu.Game/Screens/Multi/Match/Components/HeaderButton.cs create mode 100644 osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs index 37b3f6030d..0272581a8f 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Allocation; using osu.Game.Beatmaps; @@ -13,6 +15,14 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseMatchInfo : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(Info), + typeof(HeaderButton), + typeof(ReadyButton), + typeof(ViewBeatmapButton) + }; + [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 4e3349056c..db71f7d2fe 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -98,7 +98,7 @@ namespace osu.Game.Screens.Multi.Match.Components tabStrip.Colour = colours.Yellow; } - private class BeatmapSelectButton : TriangleButton + private class BeatmapSelectButton : HeaderButton { private readonly IBindable roomIDBind = new Bindable(); diff --git a/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs b/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs new file mode 100644 index 0000000000..30fe609ede --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs @@ -0,0 +1,48 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class HeaderButton : TriangleButton + { + [BackgroundDependencyLoader] + private void load() + { + BackgroundColour = OsuColour.FromHex(@"1187aa"); + + Triangles.ColourLight = OsuColour.FromHex(@"277b9c"); + Triangles.ColourDark = OsuColour.FromHex(@"1f6682"); + Triangles.TriangleScale = 1.5f; + + Add(new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 1f, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.15f, + Blending = BlendingMode.Additive, + }, + }); + } + + protected override SpriteText CreateText() => new OsuSpriteText + { + Depth = -1, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Font = @"Exo2.0-Light", + TextSize = 30, + }; + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index f63fed8152..4912c95327 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -23,8 +23,6 @@ namespace osu.Game.Screens.Multi.Match.Components { public class Info : Container { - public const float HEIGHT = 156; - public Action OnStart; private readonly OsuSpriteText availabilityStatus; @@ -41,7 +39,7 @@ namespace osu.Game.Screens.Multi.Match.Components public Info() { RelativeSizeAxes = Axes.X; - Height = HEIGHT; + AutoSizeAxes = Axes.Y; BeatmapTypeInfo beatmapTypeInfo; OsuSpriteText name; @@ -56,14 +54,16 @@ namespace osu.Game.Screens.Multi.Match.Components }, new Container { - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, Children = new Drawable[] { - new Container + new FillFlowContainer { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), Padding = new MarginPadding { Vertical = 20 }, Children = new Drawable[] { @@ -75,12 +75,10 @@ namespace osu.Game.Screens.Multi.Match.Components { name = new OsuSpriteText { TextSize = 30 }, availabilityStatus = new OsuSpriteText { TextSize = 14 }, - }, + } }, new FillFlowContainer { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Children = new Drawable[] @@ -93,18 +91,25 @@ namespace osu.Game.Screens.Multi.Match.Components }, } } - }, }, - new ReadyButton + new FillFlowContainer { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Y, - Size = new Vector2(200, 1), - Padding = new MarginPadding { Vertical = 10 }, - Action = () => OnStart?.Invoke() - }, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.X, + Height = 70, + Spacing = new Vector2(10, 0), + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new ViewBeatmapButton(), + new ReadyButton + { + Action = () => OnStart?.Invoke() + } + } + } }, }, }; diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index f0ca013b62..ec07b5ec09 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -1,50 +1,19 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; +using osuTK; namespace osu.Game.Screens.Multi.Match.Components { - public class ReadyButton : TriangleButton + public class ReadyButton : HeaderButton { - [BackgroundDependencyLoader] - private void load() + public ReadyButton() { - BackgroundColour = OsuColour.FromHex(@"1187aa"); - - Triangles.ColourLight = OsuColour.FromHex(@"277b9c"); - Triangles.ColourDark = OsuColour.FromHex(@"1f6682"); - Triangles.TriangleScale = 1.5f; + RelativeSizeAxes = Axes.Y; + Size = new Vector2(200, 1); Text = "Start"; - - Add(new Container - { - RelativeSizeAxes = Axes.Both, - Alpha = 1f, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0.15f, - Blending = BlendingMode.Additive, - }, - }); } - - protected override SpriteText CreateText() => new OsuSpriteText - { - Depth = -1, - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Font = @"Exo2.0-Light", - TextSize = 30, - }; } } diff --git a/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs b/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs new file mode 100644 index 0000000000..e9cff656c2 --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osuTK; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class ViewBeatmapButton : HeaderButton + { + public ViewBeatmapButton() + { + RelativeSizeAxes = Axes.Y; + Size = new Vector2(200, 1); + + Text = "View beatmap"; + } + } +} diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 1d713dd0b1..82b234e9c8 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -66,19 +66,21 @@ namespace osu.Game.Screens.Multi.Match Children = new Drawable[] { - header = new Components.Header - { - Depth = -1, - }, - info = new Info - { - Margin = new MarginPadding { Top = Components.Header.HEIGHT }, - OnStart = onStart - }, - participants = new Participants + new GridContainer { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = Components.Header.HEIGHT + Info.HEIGHT }, + Content = new[] + { + new Drawable[] { header = new Components.Header { Depth = -1 } }, + new Drawable[] { info = new Info { OnStart = onStart } }, + new Drawable[] { participants = new Participants { RelativeSizeAxes = Axes.Both } }, + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed), + } }, new Container { From 3de65238a2b5a41a62bde845ca8a675dbe3a70eb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 14:33:50 +0900 Subject: [PATCH 052/220] Completely hide the select beatmap button for now --- osu.Game/Screens/Multi/Match/Components/Header.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index db71f7d2fe..4b831ed3c6 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; using osuTK.Graphics; @@ -114,7 +113,7 @@ namespace osu.Game.Screens.Multi.Match.Components private void load() { roomIDBind.BindTo(room.RoomID); - roomIDBind.BindValueChanged(v => Enabled.Value = !v.HasValue, true); + roomIDBind.BindValueChanged(v => this.FadeTo(v.HasValue ? 0 : 1), true); } } From 28192aef90103a6e80096aecb0b0534db331546d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 15:03:49 +0900 Subject: [PATCH 053/220] Fix nullref --- osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 2b4c69d332..7b42672c2e 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -59,11 +59,11 @@ namespace osu.Game.Online.API.Requests.Responses public BeatmapInfo ToBeatmap(RulesetStore rulesets) { - var set = BeatmapSet.ToBeatmapSet(rulesets); + var set = BeatmapSet?.ToBeatmapSet(rulesets); return new BeatmapInfo { - Metadata = set.Metadata, + Metadata = set?.Metadata ?? this, Ruleset = rulesets.GetRuleset(ruleset), StarDifficulty = starDifficulty, OnlineBeatmapID = OnlineBeatmapID, From 83bf37a302395fa3cee5112afe3b628f88fd0f9c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 15:04:04 +0900 Subject: [PATCH 054/220] Enable/disable the view beatmap + ready buttons based on beatmap presence --- .../Screens/Multi/Match/Components/Info.cs | 9 +++- .../Multi/Match/Components/ReadyButton.cs | 41 +++++++++++++++++++ .../Match/Components/ViewBeatmapButton.cs | 27 ++++++++++++ osu.Game/Screens/Multi/Match/MatchScreen.cs | 1 + 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index 4912c95327..1750323486 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -41,6 +41,8 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + ReadyButton readyButton; + ViewBeatmapButton viewBeatmapButton; BeatmapTypeInfo beatmapTypeInfo; OsuSpriteText name; ModDisplay modDisplay; @@ -103,8 +105,8 @@ namespace osu.Game.Screens.Multi.Match.Components Direction = FillDirection.Horizontal, Children = new Drawable[] { - new ViewBeatmapButton(), - new ReadyButton + viewBeatmapButton = new ViewBeatmapButton(), + readyButton = new ReadyButton { Action = () => OnStart?.Invoke() } @@ -118,6 +120,9 @@ namespace osu.Game.Screens.Multi.Match.Components beatmapTypeInfo.Type.BindTo(Type); modDisplay.Current.BindTo(Mods); + viewBeatmapButton.Beatmap.BindTo(Beatmap); + readyButton.Beatmap.BindTo(Beatmap); + Availability.BindValueChanged(_ => updateAvailabilityStatus()); Status.BindValueChanged(_ => updateAvailabilityStatus()); Name.BindValueChanged(n => name.Text = n); diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index ec07b5ec09..c52a3be7cb 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -1,13 +1,22 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Game.Beatmaps; using osuTK; namespace osu.Game.Screens.Multi.Match.Components { public class ReadyButton : HeaderButton { + public readonly IBindable Beatmap = new Bindable(); + + [Resolved] + private BeatmapManager beatmaps { get; set; } + public ReadyButton() { RelativeSizeAxes = Axes.Y; @@ -15,5 +24,37 @@ namespace osu.Game.Screens.Multi.Match.Components Text = "Start"; } + + [BackgroundDependencyLoader] + private void load() + { + beatmaps.ItemAdded += beatmapAdded; + + Beatmap.BindValueChanged(updateEnabledState, true); + } + + private void updateEnabledState(BeatmapInfo beatmap) + { + if (beatmap?.OnlineBeatmapID == null) + { + Enabled.Value = false; + return; + } + + Enabled.Value = beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID) != null; + } + + private void beatmapAdded(BeatmapSetInfo model, bool existing, bool silent) + { + if (model.Beatmaps.Any(b => b.OnlineBeatmapID == Beatmap.Value.OnlineBeatmapID)) + Schedule(() => Enabled.Value = true); + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + beatmaps.ItemAdded -= beatmapAdded; + } } } diff --git a/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs b/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs index e9cff656c2..82d0761fbf 100644 --- a/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs @@ -1,13 +1,21 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Game.Beatmaps; using osuTK; namespace osu.Game.Screens.Multi.Match.Components { public class ViewBeatmapButton : HeaderButton { + public readonly IBindable Beatmap = new Bindable(); + + [Resolved(CanBeNull = true)] + private OsuGame osuGame { get; set; } + public ViewBeatmapButton() { RelativeSizeAxes = Axes.Y; @@ -15,5 +23,24 @@ namespace osu.Game.Screens.Multi.Match.Components Text = "View beatmap"; } + + [BackgroundDependencyLoader] + private void load() + { + if (osuGame != null) + Beatmap.BindValueChanged(updateAction, true); + } + + private void updateAction(BeatmapInfo beatmap) + { + if (beatmap == null) + { + Enabled.Value = false; + return; + } + + Action = () => osuGame.ShowBeatmap(beatmap.OnlineBeatmapID ?? 0); + Enabled.Value = true; + } } } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 82b234e9c8..dba9c8c14e 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -140,6 +140,7 @@ namespace osu.Game.Screens.Multi.Match info.Beatmap.Value = item.Beatmap; info.Mods.Value = item.RequiredMods; + // Todo: item.Beatmap can be null here... Beatmap.Value = beatmapManager.GetWorkingBeatmap(item.Beatmap); } From e3ad226075f96422f8bdb6989e9044a7bb0378d5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 16:11:00 +0900 Subject: [PATCH 055/220] Use the local beatmap if existing, fixing player not loading objects --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index dba9c8c14e..00e63c11f3 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -141,7 +141,9 @@ namespace osu.Game.Screens.Multi.Match info.Mods.Value = item.RequiredMods; // Todo: item.Beatmap can be null here... - Beatmap.Value = beatmapManager.GetWorkingBeatmap(item.Beatmap); + var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.BeatmapID) ?? item.Beatmap; + + Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); } private void onStart() From edefdb18f81eb5fb058191b527a9a85c311acb09 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 16:16:38 +0900 Subject: [PATCH 056/220] Fix beatmap not having any mods when going into play --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 00e63c11f3..5fcbc3a669 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -142,8 +142,8 @@ namespace osu.Game.Screens.Multi.Match // Todo: item.Beatmap can be null here... var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.BeatmapID) ?? item.Beatmap; - Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); + Beatmap.Value.Mods.Value = item.RequiredMods.ToArray(); } private void onStart() From 5f0069eb837a8300efc0f90c35cf1415a0fe4ade Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 17:35:05 +0900 Subject: [PATCH 057/220] Fix incorrect ruleset being sent to API --- osu.Game/Screens/Select/MatchSongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 10f29d929d..2008c9b783 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -19,6 +19,7 @@ namespace osu.Game.Screens.Select { Beatmap = Beatmap.Value.BeatmapInfo, Ruleset = Ruleset.Value, + RulesetID = Ruleset.Value.ID ?? 0 }; item.RequiredMods.AddRange(SelectedMods.Value); From de0fc2a0deae3e509751e72777de33be8eeec1fa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 17:35:18 +0900 Subject: [PATCH 058/220] Fix beatmap + ruleset being changeable --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 16 ++++++++++++++-- osu.Game/Screens/Multi/Multiplayer.cs | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 5fcbc3a669..abcec16089 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -32,6 +32,9 @@ namespace osu.Game.Screens.Multi.Match protected override Drawable TransitionContent => participants; + public override bool AllowBeatmapRulesetChange => allowBeatmapRulesetChange; + private bool allowBeatmapRulesetChange; + public override string Title => room.Name.Value; public override string ShortTitle => "room"; @@ -140,10 +143,19 @@ namespace osu.Game.Screens.Multi.Match info.Beatmap.Value = item.Beatmap; info.Mods.Value = item.RequiredMods; + allowBeatmapRulesetChange = true; + // Todo: item.Beatmap can be null here... var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.BeatmapID) ?? item.Beatmap; - Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); - Beatmap.Value.Mods.Value = item.RequiredMods.ToArray(); + + Schedule(() => + { + Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); + Beatmap.Value.Mods.Value = item.RequiredMods.ToArray(); + Ruleset.Value = item.Ruleset; + + allowBeatmapRulesetChange = false; + }); } private void onStart() diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 0150452677..0169d32c75 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -19,6 +19,10 @@ namespace osu.Game.Screens.Multi { private readonly MultiplayerWaveContainer waves; + public override bool AllowBeatmapRulesetChange => currentScreen?.AllowBeatmapRulesetChange ?? base.AllowBeatmapRulesetChange; + + private OsuScreen currentScreen; + public Multiplayer() { Child = waves = new MultiplayerWaveContainer @@ -58,6 +62,8 @@ namespace osu.Game.Screens.Multi new Header(loungeScreen) }); + screenAdded(loungeScreen); + loungeScreen.Exited += s => Exit(); } @@ -96,6 +102,19 @@ namespace osu.Game.Screens.Multi base.LogoExiting(logo); } + private void screenAdded(Screen newScreen) + { + currentScreen = (OsuScreen)newScreen; + + newScreen.ModePushed += screenAdded; + newScreen.Exited += screenRemoved; + } + + private void screenRemoved(Screen newScreen) + { + currentScreen = (OsuScreen)newScreen; + } + private class MultiplayerWaveContainer : WaveContainer { protected override bool StartHidden => true; From d9fc7c7d66dd08532107c6fc18df7055105f1375 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 19:51:27 +0900 Subject: [PATCH 059/220] Separate out Leaderboard into BeatmapLeaderboard --- osu.Game.Tests/Visual/TestCaseLeaderboard.cs | 5 +- .../Online/API/Requests/GetScoresRequest.cs | 6 +- .../Leaderboards/DrawableRank.cs | 4 +- .../Leaderboards/Leaderboard.cs | 113 +++++------------- .../Leaderboards/LeaderboardScore.cs | 79 +++++++----- .../Leaderboards/MessagePlaceholder.cs | 2 +- .../Leaderboards/Placeholder.cs | 2 +- .../Leaderboards/PlaceholderState.cs | 2 +- .../RetrievalFailurePlaceholder.cs | 2 +- .../BeatmapSet/Scores/DrawableScore.cs | 2 +- .../BeatmapSet/Scores/DrawableTopScore.cs | 2 +- .../Sections/Ranks/DrawableProfileScore.cs | 2 +- .../Sections/Recent/DrawableRecentActivity.cs | 2 +- .../Screens/Ranking/ResultsPageRanking.cs | 2 +- osu.Game/Screens/Ranking/ResultsPageScore.cs | 2 +- osu.Game/Screens/Select/BeatmapDetailArea.cs | 6 +- .../Select/Leaderboards/BeatmapLeaderboard.cs | 87 ++++++++++++++ ...ardScope.cs => BeatmapLeaderboardScope.cs} | 2 +- .../Leaderboards/BeatmapLeaderboardScore.cs | 34 ++++++ 19 files changed, 224 insertions(+), 132 deletions(-) rename osu.Game/{Screens/Select => Online}/Leaderboards/DrawableRank.cs (96%) rename osu.Game/{Screens/Select => Online}/Leaderboards/Leaderboard.cs (76%) rename osu.Game/{Screens/Select => Online}/Leaderboards/LeaderboardScore.cs (87%) rename osu.Game/{Screens/Select => Online}/Leaderboards/MessagePlaceholder.cs (94%) rename osu.Game/{Screens/Select => Online}/Leaderboards/Placeholder.cs (94%) rename osu.Game/{Screens/Select => Online}/Leaderboards/PlaceholderState.cs (88%) rename osu.Game/{Screens/Select => Online}/Leaderboards/RetrievalFailurePlaceholder.cs (97%) create mode 100644 osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs rename osu.Game/Screens/Select/Leaderboards/{LeaderboardScope.cs => BeatmapLeaderboardScope.cs} (87%) create mode 100644 osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScore.cs diff --git a/osu.Game.Tests/Visual/TestCaseLeaderboard.cs b/osu.Game.Tests/Visual/TestCaseLeaderboard.cs index f7630f0902..10d7eaee8a 100644 --- a/osu.Game.Tests/Visual/TestCaseLeaderboard.cs +++ b/osu.Game.Tests/Visual/TestCaseLeaderboard.cs @@ -11,6 +11,7 @@ using osu.Framework.Allocation; using osuTK; using System.Linq; using osu.Game.Beatmaps; +using osu.Game.Online.Leaderboards; using osu.Game.Rulesets; using osu.Game.Scoring; @@ -36,7 +37,7 @@ namespace osu.Game.Tests.Visual Origin = Anchor.Centre, Anchor = Anchor.Centre, Size = new Vector2(550f, 450f), - Scope = LeaderboardScope.Global, + Scope = BeatmapLeaderboardScope.Global, }); AddStep(@"New Scores", newScores); @@ -275,7 +276,7 @@ namespace osu.Game.Tests.Visual }; } - private class FailableLeaderboard : Leaderboard + private class FailableLeaderboard : BeatmapLeaderboard { public void SetRetrievalState(PlaceholderState state) { diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 2751dd956b..ae2c7dc269 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -13,15 +13,15 @@ namespace osu.Game.Online.API.Requests public class GetScoresRequest : APIRequest { private readonly BeatmapInfo beatmap; - private readonly LeaderboardScope scope; + private readonly BeatmapLeaderboardScope scope; private readonly RulesetInfo ruleset; - public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, LeaderboardScope scope = LeaderboardScope.Global) + public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global) { if (!beatmap.OnlineBeatmapID.HasValue) throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}."); - if (scope == LeaderboardScope.Local) + if (scope == BeatmapLeaderboardScope.Local) throw new InvalidOperationException("Should not attempt to request online scores for a local scoped leaderboard"); this.beatmap = beatmap; diff --git a/osu.Game/Screens/Select/Leaderboards/DrawableRank.cs b/osu.Game/Online/Leaderboards/DrawableRank.cs similarity index 96% rename from osu.Game/Screens/Select/Leaderboards/DrawableRank.cs rename to osu.Game/Online/Leaderboards/DrawableRank.cs index 3258a62adf..1c68c64180 100644 --- a/osu.Game/Screens/Select/Leaderboards/DrawableRank.cs +++ b/osu.Game/Online/Leaderboards/DrawableRank.cs @@ -2,14 +2,14 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.Extensions; using osu.Game.Scoring; -namespace osu.Game.Screens.Select.Leaderboards +namespace osu.Game.Online.Leaderboards { public class DrawableRank : Container { diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs similarity index 76% rename from osu.Game/Screens/Select/Leaderboards/Leaderboard.cs rename to osu.Game/Online/Leaderboards/Leaderboard.cs index a65cc6f096..8e83c8ad5a 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -3,38 +3,30 @@ using System; using System.Collections.Generic; -using osuTK; -using osuTK.Graphics; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Threading; -using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; -using osu.Game.Online.API.Requests; -using System.Linq; -using osu.Framework.Configuration; -using osu.Game.Rulesets; -using osu.Game.Scoring; +using osu.Game.Screens.Select.Leaderboards; +using osuTK; +using osuTK.Graphics; -namespace osu.Game.Screens.Select.Leaderboards +namespace osu.Game.Online.Leaderboards { - public class Leaderboard : Container + public abstract class Leaderboard : Container { private const double fade_duration = 300; private readonly ScrollContainer scrollContainer; private readonly Container placeholderContainer; - private FillFlowContainer scrollFlow; - - private readonly IBindable ruleset = new Bindable(); - - public Action ScoreSelected; + private FillFlowContainer> scrollFlow; private readonly LoadingAnimation loading; @@ -42,9 +34,9 @@ namespace osu.Game.Screens.Select.Leaderboards private bool scoresLoadedOnce; - private IEnumerable scores; + private IEnumerable scores; - public IEnumerable Scores + public IEnumerable Scores { get { return scores; } set @@ -64,13 +56,13 @@ namespace osu.Game.Screens.Select.Leaderboards // ensure placeholder is hidden when displaying scores PlaceholderState = PlaceholderState.Successful; - var flow = scrollFlow = new FillFlowContainer + var flow = scrollFlow = new FillFlowContainer> { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Spacing = new Vector2(0f, 5f), Padding = new MarginPadding { Top = 10, Bottom = 5 }, - ChildrenEnumerable = scores.Select((s, index) => new LeaderboardScore(s, index + 1) { Action = () => ScoreSelected?.Invoke(s) }) + ChildrenEnumerable = scores.Select((s, index) => CreateScoreVisualiser(s, index + 1)) }; // schedule because we may not be loaded yet (LoadComponentAsync complains). @@ -96,18 +88,18 @@ namespace osu.Game.Screens.Select.Leaderboards } } - private LeaderboardScope scope; + private TScope scope; - public LeaderboardScope Scope + public TScope Scope { get { return scope; } set { - if (value == scope) + if (value.Equals(scope)) return; scope = value; - updateScores(); + UpdateScores(); } } @@ -137,7 +129,7 @@ namespace osu.Game.Screens.Select.Leaderboards case PlaceholderState.NetworkFailure: replacePlaceholder(new RetrievalFailurePlaceholder { - OnRetry = updateScores, + OnRetry = UpdateScores, }); break; case PlaceholderState.Unavailable: @@ -159,7 +151,7 @@ namespace osu.Game.Screens.Select.Leaderboards } } - public Leaderboard() + protected Leaderboard() { Children = new Drawable[] { @@ -177,36 +169,14 @@ namespace osu.Game.Screens.Select.Leaderboards } private APIAccess api; - private BeatmapInfo beatmap; - - [Resolved] - private ScoreManager scoreManager { get; set; } private ScheduledDelegate pendingUpdateScores; - public BeatmapInfo Beatmap - { - get { return beatmap; } - set - { - if (beatmap == value) - return; - - beatmap = value; - Scores = null; - - updateScores(); - } - } - - [BackgroundDependencyLoader(permitNulls: true)] - private void load(APIAccess api, IBindable parentRuleset) + [BackgroundDependencyLoader(true)] + private void load(APIAccess api) { this.api = api; - ruleset.BindTo(parentRuleset); - ruleset.ValueChanged += _ => updateScores(); - if (api != null) api.OnStateChange += handleApiStateChange; } @@ -219,21 +189,17 @@ namespace osu.Game.Screens.Select.Leaderboards api.OnStateChange -= handleApiStateChange; } - public void RefreshScores() => updateScores(); + public void RefreshScores() => UpdateScores(); - private GetScoresRequest getScoresRequest; + private APIRequest getScoresRequest; private void handleApiStateChange(APIState oldState, APIState newState) { - if (Scope == LeaderboardScope.Local) - // No need to respond to API state change while current scope is local - return; - if (newState == APIState.Online) - updateScores(); + UpdateScores(); } - private void updateScores() + protected void UpdateScores() { // don't display any scores or placeholder until the first Scores_Set has been called. // this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished. @@ -245,40 +211,23 @@ namespace osu.Game.Screens.Select.Leaderboards pendingUpdateScores?.Cancel(); pendingUpdateScores = Schedule(() => { - if (Scope == LeaderboardScope.Local) - { - Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray(); - PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; - return; - } - - if (Beatmap?.OnlineBeatmapID == null) - { - PlaceholderState = PlaceholderState.Unavailable; - return; - } - if (api?.IsLoggedIn != true) { PlaceholderState = PlaceholderState.NotLoggedIn; return; } - if (Scope != LeaderboardScope.Global && !api.LocalUser.Value.IsSupporter) - { - PlaceholderState = PlaceholderState.NotSupporter; - return; - } - PlaceholderState = PlaceholderState.Retrieving; loading.Show(); - getScoresRequest = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope); - getScoresRequest.Success += r => Schedule(() => + getScoresRequest = FetchScores(scores => Schedule(() => { - Scores = r.Scores; + Scores = scores; PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; - }); + })); + + if (getScoresRequest == null) + return; getScoresRequest.Failure += e => Schedule(() => { @@ -292,6 +241,8 @@ namespace osu.Game.Screens.Select.Leaderboards }); } + protected abstract APIRequest FetchScores(Action> scoresCallback); + private Placeholder currentPlaceholder; private void replacePlaceholder(Placeholder placeholder) @@ -344,5 +295,7 @@ namespace osu.Game.Screens.Select.Leaderboards } } } + + protected abstract LeaderboardScore CreateScoreVisualiser(TScoreModel model, int index); } } diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs similarity index 87% rename from osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs rename to osu.Game/Online/Leaderboards/LeaderboardScore.cs index 1ba529c0bf..63352754a8 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -1,9 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using System.Linq; -using osuTK; -using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -14,47 +13,60 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Users; +using osuTK; +using osuTK.Graphics; -namespace osu.Game.Screens.Select.Leaderboards +namespace osu.Game.Online.Leaderboards { - public class LeaderboardScore : OsuClickableContainer + public static class LeaderboardScore { - public static readonly float HEIGHT = 60; + public const float HEIGHT = 60; + } + public abstract class LeaderboardScore : OsuClickableContainer + { public readonly int RankPosition; - public readonly ScoreInfo Score; private const float corner_radius = 5; private const float edge_margin = 5; private const float background_alpha = 0.25f; private const float rank_width = 30; + protected Container RankContainer { get; private set; } + + private readonly TScoreModel score; + private Box background; private Container content; private Drawable avatar; - private DrawableRank scoreRank; + private Drawable scoreRank; private OsuSpriteText nameLabel; private GlowingSpriteText scoreLabel; - private ScoreComponentLabel maxCombo; - private ScoreComponentLabel accuracy; private Container flagBadgeContainer; private FillFlowContainer modsContainer; - public LeaderboardScore(ScoreInfo score, int rank) + private List statisticsLabels; + + protected LeaderboardScore(TScoreModel score, int rank) { - Score = score; + this.score = score; RankPosition = rank; RelativeSizeAxes = Axes.X; - Height = HEIGHT; + Height = LeaderboardScore.HEIGHT; } [BackgroundDependencyLoader] private void load() { + var user = GetUser(score); + + statisticsLabels = GetStatistics(score).Select(s => new ScoreComponentLabel(s.icon, s.value, s.name)).ToList(); + Children = new Drawable[] { new Container @@ -102,7 +114,7 @@ namespace osu.Game.Screens.Select.Leaderboards Children = new[] { avatar = new DelayedLoadWrapper( - new Avatar(Score.User) + new Avatar(user) { RelativeSizeAxes = Axes.Both, CornerRadius = corner_radius, @@ -117,18 +129,18 @@ namespace osu.Game.Screens.Select.Leaderboards }) { RelativeSizeAxes = Axes.None, - Size = new Vector2(HEIGHT - edge_margin * 2, HEIGHT - edge_margin * 2), + Size = new Vector2(LeaderboardScore.HEIGHT - edge_margin * 2, LeaderboardScore.HEIGHT - edge_margin * 2), }, new Container { RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, - Position = new Vector2(HEIGHT - edge_margin, 0f), + Position = new Vector2(LeaderboardScore.HEIGHT - edge_margin, 0f), Children = new Drawable[] { nameLabel = new OsuSpriteText { - Text = Score.User.Username, + Text = user.Username, Font = @"Exo2.0-BoldItalic", TextSize = 23, }, @@ -149,7 +161,7 @@ namespace osu.Game.Screens.Select.Leaderboards Masking = true, Children = new Drawable[] { - new DrawableFlag(Score.User?.Country) + new DrawableFlag(user.Country) { Width = 30, RelativeSizeAxes = Axes.Y, @@ -164,11 +176,7 @@ namespace osu.Game.Screens.Select.Leaderboards Direction = FillDirection.Horizontal, Spacing = new Vector2(10f, 0f), Margin = new MarginPadding { Left = edge_margin }, - Children = new Drawable[] - { - maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString(), "Max Combo"), - accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy), "Accuracy"), - }, + Children = statisticsLabels }, }, }, @@ -183,17 +191,17 @@ namespace osu.Game.Screens.Select.Leaderboards Spacing = new Vector2(5f, 0f), Children = new Drawable[] { - scoreLabel = new GlowingSpriteText(Score.TotalScore.ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")), - new Container + scoreLabel = new GlowingSpriteText(GetTotalScore(score).ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")), + RankContainer = new Container { Size = new Vector2(40f, 20f), Children = new[] { - scoreRank = new DrawableRank(Score.Rank) + scoreRank = new DrawableRank(GetRank(score)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(40f), + Size = new Vector2(40f) }, }, }, @@ -205,7 +213,7 @@ namespace osu.Game.Screens.Select.Leaderboards Origin = Anchor.BottomRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - ChildrenEnumerable = Score.Mods.Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) }) + ChildrenEnumerable = GetMods(score).Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) }) }, }, }, @@ -216,7 +224,7 @@ namespace osu.Game.Screens.Select.Leaderboards public override void Show() { - foreach (var d in new[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, maxCombo, accuracy, modsContainer }) + foreach (var d in new[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, modsContainer }.Concat(statisticsLabels)) d.FadeOut(); Alpha = 0; @@ -243,7 +251,7 @@ namespace osu.Game.Screens.Select.Leaderboards using (BeginDelayedSequence(50, true)) { - var drawables = new Drawable[] { flagBadgeContainer, maxCombo, accuracy, modsContainer, }; + var drawables = new Drawable[] { flagBadgeContainer, modsContainer }.Concat(statisticsLabels).ToArray(); for (int i = 0; i < drawables.Length; i++) drawables[i].FadeIn(100 + i * 50); } @@ -263,6 +271,16 @@ namespace osu.Game.Screens.Select.Leaderboards base.OnHoverLost(e); } + protected abstract User GetUser(TScoreModel model); + + protected abstract IEnumerable GetMods(TScoreModel model); + + protected abstract IEnumerable<(FontAwesome icon, string value, string name)> GetStatistics(TScoreModel model); + + protected abstract int GetTotalScore(TScoreModel model); + + protected abstract ScoreRank GetRank(TScoreModel model); + private class GlowingSpriteText : Container { public GlowingSpriteText(string text, string font, int textSize, Color4 textColour, Color4 glowColour) @@ -324,8 +342,7 @@ namespace osu.Game.Screens.Select.Leaderboards public ScoreComponentLabel(FontAwesome icon, string value, string name) { this.name = name; - AutoSizeAxes = Axes.Y; - Width = 60; + AutoSizeAxes = Axes.Both; Child = content = new FillFlowContainer { diff --git a/osu.Game/Screens/Select/Leaderboards/MessagePlaceholder.cs b/osu.Game/Online/Leaderboards/MessagePlaceholder.cs similarity index 94% rename from osu.Game/Screens/Select/Leaderboards/MessagePlaceholder.cs rename to osu.Game/Online/Leaderboards/MessagePlaceholder.cs index f01a55b662..ea92836e6e 100644 --- a/osu.Game/Screens/Select/Leaderboards/MessagePlaceholder.cs +++ b/osu.Game/Online/Leaderboards/MessagePlaceholder.cs @@ -4,7 +4,7 @@ using osu.Framework.Graphics; using osu.Game.Graphics; -namespace osu.Game.Screens.Select.Leaderboards +namespace osu.Game.Online.Leaderboards { public class MessagePlaceholder : Placeholder { diff --git a/osu.Game/Screens/Select/Leaderboards/Placeholder.cs b/osu.Game/Online/Leaderboards/Placeholder.cs similarity index 94% rename from osu.Game/Screens/Select/Leaderboards/Placeholder.cs rename to osu.Game/Online/Leaderboards/Placeholder.cs index 468b43e54f..4994ce0e99 100644 --- a/osu.Game/Screens/Select/Leaderboards/Placeholder.cs +++ b/osu.Game/Online/Leaderboards/Placeholder.cs @@ -5,7 +5,7 @@ using System; using osu.Framework.Graphics; using osu.Game.Graphics.Containers; -namespace osu.Game.Screens.Select.Leaderboards +namespace osu.Game.Online.Leaderboards { public abstract class Placeholder : OsuTextFlowContainer, IEquatable { diff --git a/osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs b/osu.Game/Online/Leaderboards/PlaceholderState.cs similarity index 88% rename from osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs rename to osu.Game/Online/Leaderboards/PlaceholderState.cs index 33a56540f3..504b03432f 100644 --- a/osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs +++ b/osu.Game/Online/Leaderboards/PlaceholderState.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -namespace osu.Game.Screens.Select.Leaderboards +namespace osu.Game.Online.Leaderboards { public enum PlaceholderState { diff --git a/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs b/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs similarity index 97% rename from osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs rename to osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs index 66a7793f7c..7fed40ed1a 100644 --- a/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs +++ b/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs @@ -8,7 +8,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osuTK; -namespace osu.Game.Screens.Select.Leaderboards +namespace osu.Game.Online.Leaderboards { public class RetrievalFailurePlaceholder : Placeholder { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index f643e130aa..89416c1098 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -10,11 +10,11 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Leaderboards; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; namespace osu.Game.Overlays.BeatmapSet.Scores diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 643839fa88..6259d85bee 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -12,12 +12,12 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Leaderboards; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; -using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; namespace osu.Game.Overlays.BeatmapSet.Scores diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 1c39cb309c..18aa684664 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -6,8 +6,8 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Online.Leaderboards; using osu.Game.Rulesets.Mods; -using osu.Game.Screens.Select.Leaderboards; using osu.Game.Rulesets.UI; using osu.Game.Scoring; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index fefb289d17..8b4fb1a229 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -10,7 +10,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; -using osu.Game.Screens.Select.Leaderboards; +using osu.Game.Online.Leaderboards; namespace osu.Game.Overlays.Profile.Sections.Recent { diff --git a/osu.Game/Screens/Ranking/ResultsPageRanking.cs b/osu.Game/Screens/Ranking/ResultsPageRanking.cs index c5a5cc6ad9..3a75daaf60 100644 --- a/osu.Game/Screens/Ranking/ResultsPageRanking.cs +++ b/osu.Game/Screens/Ranking/ResultsPageRanking.cs @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Ranking Colour = colours.GrayE, RelativeSizeAxes = Axes.Both, }, - new Leaderboard + new BeatmapLeaderboard { Origin = Anchor.Centre, Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Ranking/ResultsPageScore.cs b/osu.Game/Screens/Ranking/ResultsPageScore.cs index 62103314e1..0774a63e98 100644 --- a/osu.Game/Screens/Ranking/ResultsPageScore.cs +++ b/osu.Game/Screens/Ranking/ResultsPageScore.cs @@ -19,11 +19,11 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; -using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; using osu.Framework.Graphics.Shapes; using osu.Framework.Extensions; using osu.Framework.Localisation; +using osu.Game.Online.Leaderboards; using osu.Game.Scoring; namespace osu.Game.Screens.Ranking diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index a6fbd201d0..c5c4960ed4 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Select protected override Container Content => content; public readonly BeatmapDetails Details; - public readonly Leaderboard Leaderboard; + public readonly BeatmapLeaderboard Leaderboard; private WorkingBeatmap beatmap; public WorkingBeatmap Beatmap @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Select default: Details.Hide(); - Leaderboard.Scope = (LeaderboardScope)tab - 1; + Leaderboard.Scope = (BeatmapLeaderboardScope)tab - 1; Leaderboard.Show(); break; } @@ -73,7 +73,7 @@ namespace osu.Game.Screens.Select Alpha = 0, Margin = new MarginPadding { Top = details_padding }, }, - Leaderboard = new Leaderboard + Leaderboard = new BeatmapLeaderboard { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs new file mode 100644 index 0000000000..b0cfad314c --- /dev/null +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -0,0 +1,87 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Game.Beatmaps; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.Leaderboards; +using osu.Game.Rulesets; +using osu.Game.Scoring; + +namespace osu.Game.Screens.Select.Leaderboards +{ + public class BeatmapLeaderboard : Leaderboard + { + public Action ScoreSelected; + + private BeatmapInfo beatmap; + + public BeatmapInfo Beatmap + { + get { return beatmap; } + set + { + if (beatmap == value) + return; + + beatmap = value; + Scores = null; + + UpdateScores(); + } + } + + [Resolved] + private ScoreManager scoreManager { get; set; } + + [Resolved] + private IBindable ruleset { get; set; } + + [Resolved] + private APIAccess api { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + ruleset.ValueChanged += _ => UpdateScores(); + } + + protected override APIRequest FetchScores(Action> scoresCallback) + { + if (Scope == BeatmapLeaderboardScope.Local) + { + Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray(); + PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; + return null; + } + + if (Beatmap?.OnlineBeatmapID == null) + { + PlaceholderState = PlaceholderState.Unavailable; + return null; + } + + if (Scope != BeatmapLeaderboardScope.Global && !api.LocalUser.Value.IsSupporter) + { + PlaceholderState = PlaceholderState.NotSupporter; + return null; + } + + var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope); + + req.Success += r => scoresCallback?.Invoke(r.Scores); + + return req; + } + + protected override LeaderboardScore CreateScoreVisualiser(ScoreInfo model, int index) => new BeatmapLeaderboardScore(model, index) + { + Action = () => ScoreSelected?.Invoke(model) + }; + } +} diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScope.cs similarity index 87% rename from osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs rename to osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScope.cs index 761f53a5e8..39d9580792 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScope.cs @@ -3,7 +3,7 @@ namespace osu.Game.Screens.Select.Leaderboards { - public enum LeaderboardScope + public enum BeatmapLeaderboardScope { Local, Country, diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScore.cs new file mode 100644 index 0000000000..098fff4052 --- /dev/null +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScore.cs @@ -0,0 +1,34 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Graphics; +using osu.Game.Online.Leaderboards; +using osu.Game.Rulesets.Mods; +using osu.Game.Scoring; +using osu.Game.Users; + +namespace osu.Game.Screens.Select.Leaderboards +{ + public class BeatmapLeaderboardScore : LeaderboardScore + { + public BeatmapLeaderboardScore(ScoreInfo score, int rank) + : base(score, rank) + { + } + + protected override User GetUser(ScoreInfo model) => model.User; + + protected override IEnumerable GetMods(ScoreInfo model) => model.Mods; + + protected override IEnumerable<(FontAwesome icon, string value, string name)> GetStatistics(ScoreInfo model) => new[] + { + (FontAwesome.fa_link, model.MaxCombo.ToString(), "Max Combo"), + (FontAwesome.fa_crosshairs, string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy), "Accuracy") + }; + + protected override int GetTotalScore(ScoreInfo model) => model.TotalScore; + + protected override ScoreRank GetRank(ScoreInfo model) => model.Rank; + } +} From e8007ac37fe9f90b23bb369cf11a226c4a0a2d1a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 19:52:03 +0900 Subject: [PATCH 060/220] Implement multiplayer room leaderboard --- .../Visual/TestCaseMatchLeaderboard.cs | 68 ++++++++++ osu.Game/Online/Leaderboards/Leaderboard.cs | 1 - .../Match/Components/MatchLeaderboard.cs | 119 ++++++++++++++++++ osu.Game/Screens/Multi/Match/MatchScreen.cs | 21 +++- 4 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs create mode 100644 osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs b/osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs new file mode 100644 index 0000000000..cf475de1f0 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs @@ -0,0 +1,68 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using Newtonsoft.Json; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseMatchLeaderboard : OsuTestCase + { + public TestCaseMatchLeaderboard() + { + Add(new MatchLeaderboard(new Room { RoomID = { Value = 3 } }) + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Size = new Vector2(550f, 450f), + Scope = MatchLeaderboardScope.Overall, + }); + } + + [Resolved] + private APIAccess api { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + var req = new GetRoomScoresRequest(); + req.Success += v => { }; + req.Failure += _ => { }; + + api.Queue(req); + } + + private class GetRoomScoresRequest : APIRequest> + { + protected override string Target => "rooms/3/leaderboard"; + } + + private class RoomScore + { + [JsonProperty("user")] + public User User { get; set; } + + [JsonProperty("accuracy")] + public double Accuracy { get; set; } + + [JsonProperty("total_score")] + public int TotalScore { get; set; } + + [JsonProperty("pp")] + public double PP { get; set; } + + [JsonProperty("attempts")] + public int TotalAttempts { get; set; } + + [JsonProperty("completed")] + public int CompletedAttempts { get; set; } + } + } +} diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 8e83c8ad5a..83cc289bc1 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -13,7 +13,6 @@ using osu.Framework.Threading; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; -using osu.Game.Screens.Select.Leaderboards; using osuTK; using osuTK.Graphics; diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs new file mode 100644 index 0000000000..ef1021bac6 --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -0,0 +1,119 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using osu.Framework.Allocation; +using osu.Game.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.Leaderboards; +using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets.Mods; +using osu.Game.Scoring; +using osu.Game.Users; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class MatchLeaderboard : Leaderboard + { + private readonly Room room; + + public MatchLeaderboard(Room room) + { + this.room = room; + } + + [BackgroundDependencyLoader] + private void load() + { + room.RoomID.BindValueChanged(_ => + { + Scores = null; + UpdateScores(); + }, true); + } + + protected override APIRequest FetchScores(Action> scoresCallback) + { + if (room.RoomID == null) + return null; + + var req = new GetRoomScoresRequest(room.RoomID.Value ?? 0); + + req.Success += r => scoresCallback?.Invoke(r); + + return req; + } + + protected override LeaderboardScore CreateScoreVisualiser(RoomScore model, int index) => new MatchLeaderboardScore(model, index); + + private class GetRoomScoresRequest : APIRequest> + { + private readonly int roomId; + + public GetRoomScoresRequest(int roomId) + { + this.roomId = roomId; + } + + protected override string Target => $@"rooms/{roomId}/leaderboard"; + } + } + + public class MatchLeaderboardScore : LeaderboardScore + { + public MatchLeaderboardScore(RoomScore score, int rank) + : base(score, rank) + { + } + + [BackgroundDependencyLoader] + private void load() + { + RankContainer.Alpha = 0; + } + + protected override User GetUser(RoomScore model) => model.User; + + protected override IEnumerable GetMods(RoomScore model) => Enumerable.Empty(); // Not implemented yet + + protected override IEnumerable<(FontAwesome icon, string value, string name)> GetStatistics(RoomScore model) => new[] + { + (FontAwesome.fa_crosshairs, string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy), "Accuracy"), + (FontAwesome.fa_refresh, model.TotalAttempts.ToString(), "Total Attempts"), + (FontAwesome.fa_check, model.CompletedAttempts.ToString(), "Completed Beatmaps"), + }; + + protected override int GetTotalScore(RoomScore model) => model.TotalScore; + + protected override ScoreRank GetRank(RoomScore model) => ScoreRank.S; + } + + public enum MatchLeaderboardScope + { + Overall + } + + public class RoomScore + { + [JsonProperty("user")] + public User User { get; set; } + + [JsonProperty("accuracy")] + public double Accuracy { get; set; } + + [JsonProperty("total_score")] + public int TotalScore { get; set; } + + [JsonProperty("pp")] + public double PP { get; set; } + + [JsonProperty("attempts")] + public int TotalAttempts { get; set; } + + [JsonProperty("completed")] + public int CompletedAttempts { get; set; } + } +} diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index abcec16089..d4e73308c3 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -76,7 +76,26 @@ namespace osu.Game.Screens.Multi.Match { new Drawable[] { header = new Components.Header { Depth = -1 } }, new Drawable[] { info = new Info { OnStart = onStart } }, - new Drawable[] { participants = new Participants { RelativeSizeAxes = Axes.Both } }, + new Drawable[] + { + new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + participants = new Participants { RelativeSizeAxes = Axes.Both }, + new MatchLeaderboard(room) { RelativeSizeAxes = Axes.Both } + }, + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Distributed), + new Dimension(GridSizeMode.Relative, 0.5f), + } + } + }, }, RowDimensions = new[] { From 9726eea0d02c07029e4cbc7324bd57043630e99a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 21:09:17 +0900 Subject: [PATCH 061/220] Basic score submission implementation --- osu.Game/Online/Multiplayer/Room.cs | 5 +- osu.Game/Scoring/ScoreInfo.cs | 25 ++++- osu.Game/Screens/Multi/Match/MatchScreen.cs | 2 +- .../Screens/Multi/Play/TimeshiftPlayer.cs | 97 +++++++++++++++++++ 4 files changed, 125 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 5e9fc4f008..5c24827d44 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -64,6 +64,9 @@ namespace osu.Game.Online.Multiplayer public class PlaylistItem { + [JsonProperty("id")] + public int ID { get; set; } + [JsonProperty("beatmap")] private APIBeatmap beatmap { get; set; } @@ -73,7 +76,7 @@ namespace osu.Game.Online.Multiplayer public BeatmapInfo Beatmap { get; set; } [JsonProperty("beatmap_id")] - public int BeatmapID => 847296; //Beatmap.OnlineBeatmapID ?? 0; + public int BeatmapID => Beatmap.OnlineBeatmapID ?? 0; [JsonProperty("ruleset_id")] public int RulesetID { get; set; } diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index fb894e621e..a689590819 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -19,25 +19,38 @@ namespace osu.Game.Scoring { public int ID { get; set; } + [JsonProperty("rank")] public ScoreRank Rank { get; set; } + [JsonProperty("total_score")] public int TotalScore { get; set; } + [JsonProperty("accuracy")] [Column(TypeName="DECIMAL(1,4)")] public double Accuracy { get; set; } + [JsonIgnore] public double? PP { get; set; } + [JsonProperty("max_combo")] public int MaxCombo { get; set; } - public int Combo { get; set; } + [JsonIgnore] + public int Combo { get; set; } // Todo: Shouldn't exist in here + [JsonIgnore] public int RulesetID { get; set; } + [JsonProperty("passed")] + [NotMapped] + public bool Passed { get; set; } = true; + + [JsonIgnore] public virtual RulesetInfo Ruleset { get; set; } private Mod[] mods; + [JsonProperty("mods")] [NotMapped] public Mod[] Mods { @@ -62,6 +75,7 @@ namespace osu.Game.Scoring private string modsJson; + [JsonIgnore] [Column("Mods")] public string ModsJson { @@ -87,6 +101,7 @@ namespace osu.Game.Scoring [JsonIgnore] public User User; + [JsonIgnore] [Column("User")] public string UserString { @@ -97,15 +112,19 @@ namespace osu.Game.Scoring [JsonIgnore] public int BeatmapInfoID { get; set; } + [JsonIgnore] public virtual BeatmapInfo Beatmap { get; set; } + [JsonIgnore] public long? OnlineScoreID { get; set; } + [JsonIgnore] public DateTimeOffset Date { get; set; } - [JsonIgnore] + [JsonProperty("statistics")] public Dictionary Statistics = new Dictionary(); + [JsonIgnore] [Column("Statistics")] public string StatisticsJson { @@ -125,8 +144,10 @@ namespace osu.Game.Scoring [JsonIgnore] public List Files { get; set; } + [JsonIgnore] public string Hash { get; set; } + [JsonIgnore] public bool DeletePending { get; set; } [Serializable] diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index d4e73308c3..e4e8f8e305 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -183,7 +183,7 @@ namespace osu.Game.Screens.Multi.Match { default: case GameTypeTimeshift _: - multiplayer.Push(new PlayerLoader(new TimeshiftPlayer())); + multiplayer.Push(new PlayerLoader(new TimeshiftPlayer(room.RoomID.Value ?? 0, room.Playlist.First().ID))); break; } } diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index 114d90dc79..5a9fab6aaf 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -1,11 +1,108 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Net.Http; +using Newtonsoft.Json; +using osu.Framework.Allocation; +using osu.Framework.IO.Network; +using osu.Game.Online.API; +using osu.Game.Scoring; using osu.Game.Screens.Play; namespace osu.Game.Screens.Multi.Play { public class TimeshiftPlayer : Player { + private readonly int roomId; + private readonly int playlistItemId; + + [Resolved] + private APIAccess api { get; set; } + + public TimeshiftPlayer(int roomId, int playlistItemId) + { + this.roomId = roomId; + this.playlistItemId = playlistItemId; + } + + private int token; + + [BackgroundDependencyLoader] + private void load() + { + var req = new CreateScoreRequest(roomId, playlistItemId); + req.Success += r => token = r.ID; + req.Failure += e => { }; + api.Queue(req); + } + + protected override ScoreInfo CreateScore() + { + var score = base.CreateScore(); + + var request = new SubmitScoreRequest(token, roomId, playlistItemId, score); + request.Success += () => { }; + request.Failure += e => { }; + api.Queue(request); + + return score; + } + } + + public class SubmitScoreRequest : APIRequest + { + private readonly int scoreId; + private readonly int roomId; + private readonly int playlistItemId; + private readonly ScoreInfo scoreInfo; + + public SubmitScoreRequest(int scoreId, int roomId, int playlistItemId, ScoreInfo scoreInfo) + { + this.scoreId = scoreId; + this.roomId = roomId; + this.playlistItemId = playlistItemId; + this.scoreInfo = scoreInfo; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + + req.ContentType = "application/json"; + req.Method = HttpMethod.Put; + + req.AddRaw(JsonConvert.SerializeObject(scoreInfo)); + + return req; + } + + protected override string Target => $@"rooms/{roomId}/playlist/{playlistItemId}/scores/{scoreId}"; + } + + public class CreateScoreRequest : APIRequest + { + private readonly int roomId; + private readonly int playlistItemId; + + public CreateScoreRequest(int roomId, int playlistItemId) + { + this.roomId = roomId; + this.playlistItemId = playlistItemId; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + return req; + } + + protected override string Target => $@"rooms/{roomId}/playlist/{playlistItemId}/scores"; + } + + public class CreateScoreResult + { + [JsonProperty("id")] + public int ID { get; set; } } } From 983a45c4d8cbdf2e1a92e70789dfa044005d67c3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Dec 2018 21:21:02 +0900 Subject: [PATCH 062/220] Fix invalid value --- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index ef1021bac6..9d4ad3cb22 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Multi.Match.Components public int TotalScore { get; set; } [JsonProperty("pp")] - public double PP { get; set; } + public double? PP { get; set; } [JsonProperty("attempts")] public int TotalAttempts { get; set; } From 2fd2425cc40791f7f6e75f6bb4dc3e721acab35b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Dec 2018 11:04:38 +0900 Subject: [PATCH 063/220] Fix playlist deserialisation for creating rooms --- osu.Game/Online/Multiplayer/Room.cs | 65 +++++++++++++++------------ osu.Game/Screens/Multi/RoomManager.cs | 14 +++--- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 5c24827d44..0317b3c3e8 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -59,6 +59,9 @@ namespace osu.Game.Online.Multiplayer Type.Value = other.Type; MaxParticipants.Value = other.MaxParticipants; Participants.Value = other.Participants.Value.ToArray(); + + Playlist.Clear(); + Playlist.AddRange(other.Playlist); } } @@ -68,15 +71,25 @@ namespace osu.Game.Online.Multiplayer public int ID { get; set; } [JsonProperty("beatmap")] - private APIBeatmap beatmap { get; set; } + private APIBeatmap apiBeatmap { get; set; } - public bool ShouldSerializebeatmap() => false; + public bool ShouldSerializeapiBeatmap() => false; + + private BeatmapInfo beatmap; [JsonIgnore] - public BeatmapInfo Beatmap { get; set; } + public BeatmapInfo Beatmap + { + get => beatmap; + set + { + beatmap = value; + BeatmapID = value?.OnlineBeatmapID ?? 0; + } + } [JsonProperty("beatmap_id")] - public int BeatmapID => Beatmap.OnlineBeatmapID ?? 0; + public int BeatmapID { get; set; } [JsonProperty("ruleset_id")] public int RulesetID { get; set; } @@ -105,37 +118,31 @@ namespace osu.Game.Online.Multiplayer set => _requiredMods = value; } - private RulesetInfo ruleset; - [JsonIgnore] - public RulesetInfo Ruleset + public RulesetInfo Ruleset { get; set; } + + public void MapObjects(BeatmapManager beatmaps, RulesetStore rulesets) { - get => ruleset; - set + // If we don't have an api beatmap, the request occurred as a result of room creation, so we can query the local beatmap instead + // Todo: Is this a bug? + Beatmap = apiBeatmap == null ? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == BeatmapID) : apiBeatmap.ToBeatmap(rulesets); + Ruleset = rulesets.GetRuleset(RulesetID); + + if (_allowedMods != null) { - ruleset = value; + AllowedMods.Clear(); + AllowedMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => _allowedMods.Any(m => m.Acronym == mod.Acronym))); - if (_allowedMods != null) - { - AllowedMods.Clear(); - AllowedMods.AddRange(value.CreateInstance().GetAllMods().Where(mod => _allowedMods.Any(m => m.Acronym == mod.Acronym))); - - _allowedMods = null; - } - - if (_requiredMods != null) - { - RequiredMods.Clear(); - RequiredMods.AddRange(value.CreateInstance().GetAllMods().Where(mod => _requiredMods.Any(m => m.Acronym == mod.Acronym))); - - _requiredMods = null; - } + _allowedMods = null; } - } - public void SetRulesets(RulesetStore rulesets) - { - Beatmap = beatmap.ToBeatmap(rulesets); + if (_requiredMods != null) + { + RequiredMods.Clear(); + RequiredMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => _requiredMods.Any(m => m.Acronym == mod.Acronym))); + + _requiredMods = null; + } } // Todo: Move this elsewhere for reusability diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index fead90f9a2..7e29aacaf4 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -63,11 +63,7 @@ namespace osu.Game.Screens.Multi { foreach (var r in result) { - foreach (var pi in r.Playlist) - { - pi.Ruleset = rulesets.GetRuleset(pi.RulesetID); - pi.SetRulesets(rulesets); - } + processPlaylist(r); var existing = rooms.FirstOrDefault(e => e.RoomID.Value == r.RoomID.Value); if (existing == null) @@ -88,6 +84,8 @@ namespace osu.Game.Screens.Multi private void addRoom(Room local, Room remote) { + processPlaylist(remote); + local.CopyFrom(remote); var existing = rooms.FirstOrDefault(e => e.RoomID.Value == local.RoomID.Value); @@ -96,6 +94,12 @@ namespace osu.Game.Screens.Multi rooms.Add(local); } + private void processPlaylist(Room room) + { + foreach (var pi in room.Playlist) + pi.MapObjects(beatmaps, rulesets); + } + private class CreateRoomRequest : APIRequest { private readonly Room room; From bf8aae8d9bc0ee44afaa4ae5b7e6b7e9b4eabc8e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Dec 2018 11:51:12 +0900 Subject: [PATCH 064/220] Boot player back to lobby if token request fails --- .../Screens/Multi/Play/TimeshiftPlayer.cs | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index 5a9fab6aaf..5d45615aa8 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -1,10 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Diagnostics; using System.Net.Http; +using System.Threading; using Newtonsoft.Json; using osu.Framework.Allocation; using osu.Framework.IO.Network; +using osu.Framework.Logging; using osu.Game.Online.API; using osu.Game.Scoring; using osu.Game.Screens.Play; @@ -25,24 +28,44 @@ namespace osu.Game.Screens.Multi.Play this.playlistItemId = playlistItemId; } - private int token; + private int? token; [BackgroundDependencyLoader] private void load() { + token = null; + + bool failed = false; + var req = new CreateScoreRequest(roomId, playlistItemId); req.Success += r => token = r.ID; - req.Failure += e => { }; + req.Failure += e => + { + failed = true; + + Logger.Error(e, "Failed to retrieve a score submission token."); + + Schedule(() => + { + ValidForResume = false; + Exit(); + }); + }; + api.Queue(req); + + while (!failed && !token.HasValue) + Thread.Sleep(1000); } protected override ScoreInfo CreateScore() { var score = base.CreateScore(); - var request = new SubmitScoreRequest(token, roomId, playlistItemId, score); - request.Success += () => { }; - request.Failure += e => { }; + Debug.Assert(token != null); + + var request = new SubmitScoreRequest(token.Value, roomId, playlistItemId, score); + request.Failure += e => Logger.Error(e, "Failed to submit score"); api.Queue(request); return score; From 84552b5cee34a159b4ef7e2ed755256fbc4bd392 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Dec 2018 11:51:28 +0900 Subject: [PATCH 065/220] Refresh leaderboard when returning to lobby --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index e4e8f8e305..ecb5ced5fa 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; @@ -41,6 +42,7 @@ namespace osu.Game.Screens.Multi.Match private readonly Components.Header header; private readonly Info info; + private readonly MatchLeaderboard leaderboard; [Cached] private readonly Room room; @@ -86,7 +88,7 @@ namespace osu.Game.Screens.Multi.Match new Drawable[] { participants = new Participants { RelativeSizeAxes = Axes.Both }, - new MatchLeaderboard(room) { RelativeSizeAxes = Axes.Both } + leaderboard = new MatchLeaderboard(room) { RelativeSizeAxes = Axes.Both } }, }, ColumnDimensions = new[] @@ -144,6 +146,13 @@ namespace osu.Game.Screens.Multi.Match playlistBind.BindTo(room.Playlist); } + protected override void OnResuming(Screen last) + { + base.OnResuming(last); + + leaderboard.RefreshScores(); + } + private void addPlaylistItem(PlaylistItem item) { playlistBind.Clear(); From 279891ae083548873791deaf067008e86785c639 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Dec 2018 13:55:39 +0900 Subject: [PATCH 066/220] Change "apply" button to say "create" instead --- .../Screens/Multi/Match/Components/RoomSettingsOverlay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index d6098674c1..4d5f572531 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -134,7 +134,7 @@ namespace osu.Game.Screens.Multi.Match.Components }, }, }, - ApplyButton = new ApplySettingsButton + ApplyButton = new CreateRoomButton { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, @@ -276,11 +276,11 @@ namespace osu.Game.Screens.Multi.Match.Components } } - private class ApplySettingsButton : TriangleButton + private class CreateRoomButton : TriangleButton { - public ApplySettingsButton() + public CreateRoomButton() { - Text = "Apply"; + Text = "Create"; } [BackgroundDependencyLoader] From cc68cf2f9546a56d9b5a460d1f4e6b8bdf2183a6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Dec 2018 14:44:54 +0900 Subject: [PATCH 067/220] Implement duration --- osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 7 ++- osu.Game/Online/Multiplayer/Room.cs | 10 +++- .../Match/Components/RoomSettingsOverlay.cs | 52 ++++++++++++++++--- osu.Game/Screens/Multi/Match/MatchScreen.cs | 2 +- 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index 19e27ddefe..f44c7de721 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual MaxParticipants = { Value = 10 }, }; - Add(overlay = new TestRoomSettingsOverlay + Add(overlay = new TestRoomSettingsOverlay(new Room()) { RelativeSizeAxes = Axes.Both, Height = 0.75f, @@ -84,6 +84,11 @@ namespace osu.Game.Tests.Visual private class TestRoomSettingsOverlay : RoomSettingsOverlay { + public TestRoomSettingsOverlay(Room room) + : base(room) + { + } + public string CurrentName { get => NameField.Text; diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 0317b3c3e8..0b10992ada 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -29,12 +29,18 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("playlist")] public readonly BindableCollection Playlist = new BindableCollection(); - [JsonProperty("duration")] - public readonly Bindable Duration = new Bindable(100); + [JsonIgnore] + public readonly Bindable Duration = new Bindable(TimeSpan.FromMinutes(30)); [JsonIgnore] public readonly Bindable MaxAttempts = new Bindable(); + [JsonProperty("duration")] + private int duration + { + get => (int)Duration.Value.TotalMinutes; + set => Duration.Value = TimeSpan.FromMinutes(value); + } // Todo: Find a better way to do this (https://github.com/ppy/osu-framework/issues/1930) [JsonProperty("max_attempts", DefaultValueHandling = DefaultValueHandling.Ignore)] private int? maxAttempts diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index 4d5f572531..a7149fbb6d 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using Humanizer; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -26,25 +28,28 @@ namespace osu.Game.Screens.Multi.Match.Components private readonly Bindable typeBind = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); private readonly IBindableCollection playlistBind = new BindableCollection(); + private readonly Bindable durationBind = new Bindable(); private readonly Container content; private readonly OsuSpriteText typeLabel; protected readonly OsuTextBox NameField, MaxParticipantsField; + protected readonly OsuDropdown DurationField; protected readonly RoomAvailabilityPicker AvailabilityPicker; protected readonly GameTypePicker TypePicker; protected readonly TriangleButton ApplyButton; protected readonly OsuPasswordTextBox PasswordField; - [Resolved] + private readonly Room room; + + [Resolved(CanBeNull = true)] private RoomManager manager { get; set; } - [Resolved] - private Room room { get; set; } - - public RoomSettingsOverlay() + public RoomSettingsOverlay(Room room) { + this.room = room; + Masking = true; Child = content = new Container @@ -121,6 +126,26 @@ namespace osu.Game.Screens.Multi.Match.Components OnCommit = (sender, text) => apply(), }, }, + new Section("DURATION") + { + Child = DurationField = new DurationDropdown + { + RelativeSizeAxes = Axes.X, + Items = new[] + { + TimeSpan.FromMinutes(30), + TimeSpan.FromHours(1), + TimeSpan.FromHours(2), + TimeSpan.FromHours(4), + TimeSpan.FromHours(8), + TimeSpan.FromHours(12), + TimeSpan.FromHours(16), + TimeSpan.FromHours(24), + TimeSpan.FromDays(3), + TimeSpan.FromDays(7) + } + } + }, new Section("PASSWORD (OPTIONAL)") { Child = PasswordField = new SettingsPasswordTextBox @@ -151,6 +176,7 @@ namespace osu.Game.Screens.Multi.Match.Components availabilityBind.ValueChanged += a => AvailabilityPicker.Current.Value = a; typeBind.ValueChanged += t => TypePicker.Current.Value = t; maxParticipantsBind.ValueChanged += m => MaxParticipantsField.Text = m?.ToString(); + durationBind.ValueChanged += d => DurationField.Current.Value = d; } [BackgroundDependencyLoader] @@ -163,6 +189,7 @@ namespace osu.Game.Screens.Multi.Match.Components availabilityBind.BindTo(room.Availability); typeBind.BindTo(room.Type); maxParticipantsBind.BindTo(room.MaxParticipants); + durationBind.BindTo(room.Duration); MaxParticipantsField.ReadOnly = true; PasswordField.ReadOnly = true; @@ -210,7 +237,7 @@ namespace osu.Game.Screens.Multi.Match.Components else maxParticipantsBind.Value = null; - manager.CreateRoom(room); + manager?.CreateRoom(room); } private class SettingsTextBox : OsuTextBox @@ -291,5 +318,18 @@ namespace osu.Game.Screens.Multi.Match.Components Triangles.ColourDark = colours.YellowDark; } } + + private class DurationDropdown : OsuDropdown + { + public DurationDropdown() + { + Menu.MaxHeight = 100; + } + + protected override string GenerateItemText(TimeSpan item) + { + return item.Humanize(); + } + } } } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index ecb5ced5fa..812f20f377 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -110,7 +110,7 @@ namespace osu.Game.Screens.Multi.Match { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Components.Header.HEIGHT }, - Child = settings = new RoomSettingsOverlay + Child = settings = new RoomSettingsOverlay(room) { RelativeSizeAxes = Axes.Both, Height = 0.9f, From 7c4fd8ca60c39039466b7a6738c9de0f790aa4b1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Dec 2018 14:45:06 +0900 Subject: [PATCH 068/220] Cleanup room definition --- .../Online/API/Requests/Responses/APIMod.cs | 12 ++ osu.Game/Online/Multiplayer/PlaylistItem.cs | 93 +++++++++++++ osu.Game/Online/Multiplayer/Room.cs | 123 ++++-------------- 3 files changed, 127 insertions(+), 101 deletions(-) create mode 100644 osu.Game/Online/API/Requests/Responses/APIMod.cs create mode 100644 osu.Game/Online/Multiplayer/PlaylistItem.cs diff --git a/osu.Game/Online/API/Requests/Responses/APIMod.cs b/osu.Game/Online/API/Requests/Responses/APIMod.cs new file mode 100644 index 0000000000..af0d0c643f --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIMod.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIMod : IMod + { + public string Acronym { get; set; } + } +} diff --git a/osu.Game/Online/Multiplayer/PlaylistItem.cs b/osu.Game/Online/Multiplayer/PlaylistItem.cs new file mode 100644 index 0000000000..e887295f4a --- /dev/null +++ b/osu.Game/Online/Multiplayer/PlaylistItem.cs @@ -0,0 +1,93 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using Newtonsoft.Json; +using osu.Framework.Configuration; +using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Online.Multiplayer +{ + public class PlaylistItem + { + [JsonProperty("id")] + public int ID { get; set; } + + [JsonProperty("beatmap_id")] + public int BeatmapID { get; set; } + + [JsonProperty("ruleset_id")] + public int RulesetID { get; set; } + + [JsonIgnore] + public BeatmapInfo Beatmap + { + get => beatmap; + set + { + beatmap = value; + BeatmapID = value?.OnlineBeatmapID ?? 0; + } + } + + [JsonIgnore] + public RulesetInfo Ruleset { get; set; } + + [JsonIgnore] + public readonly BindableCollection AllowedMods = new BindableCollection(); + + [JsonIgnore] + public readonly BindableCollection RequiredMods = new BindableCollection(); + + [JsonProperty("beatmap")] + private APIBeatmap apiBeatmap { get; set; } + + [JsonProperty("allowed_mods")] + private APIMod[] allowedMods + { + get => AllowedMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray(); + set => _allowedMods = value; + } + + [JsonProperty("required_mods")] + private APIMod[] requiredMods + { + get => RequiredMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray(); + set => _requiredMods = value; + } + + private BeatmapInfo beatmap; + private APIMod[] _allowedMods; + private APIMod[] _requiredMods; + + public void MapObjects(BeatmapManager beatmaps, RulesetStore rulesets) + { + // If we don't have an api beatmap, the request occurred as a result of room creation, so we can query the local beatmap instead + // Todo: Is this a bug? + Beatmap = apiBeatmap == null ? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == BeatmapID) : apiBeatmap.ToBeatmap(rulesets); + Ruleset = rulesets.GetRuleset(RulesetID); + + if (_allowedMods != null) + { + AllowedMods.Clear(); + AllowedMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => _allowedMods.Any(m => m.Acronym == mod.Acronym))); + + _allowedMods = null; + } + + if (_requiredMods != null) + { + RequiredMods.Clear(); + RequiredMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => _requiredMods.Any(m => m.Acronym == mod.Acronym))); + + _requiredMods = null; + } + } + + public bool ShouldSerializeID() => false; + public bool ShouldSerializeapiBeatmap() => false; + } +} diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 0b10992ada..ed85e6c31c 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -1,14 +1,11 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using osu.Framework.Configuration; -using osu.Game.Beatmaps; -using osu.Game.Online.API.Requests.Responses; -using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; using osu.Game.Users; namespace osu.Game.Online.Multiplayer @@ -16,15 +13,13 @@ namespace osu.Game.Online.Multiplayer public class Room { [JsonProperty("id")] - public Bindable RoomID { get; } = new Bindable(); + public Bindable RoomID { get; private set; } = new Bindable(); [JsonProperty("name")] - public readonly Bindable Name = new Bindable("My awesome room!"); + public Bindable Name { get; private set; } = new Bindable("My awesome room!"); [JsonProperty("host")] - public readonly Bindable Host = new Bindable(); - - public bool ShouldSerializeHost() => false; + public Bindable Host { get; private set; } = new Bindable(); [JsonProperty("playlist")] public readonly BindableCollection Playlist = new BindableCollection(); @@ -35,12 +30,28 @@ namespace osu.Game.Online.Multiplayer [JsonIgnore] public readonly Bindable MaxAttempts = new Bindable(); + [JsonIgnore] + public Bindable Status = new Bindable(new RoomStatusOpen()); + + [JsonIgnore] + public Bindable Availability = new Bindable(); + + [JsonIgnore] + public Bindable Type = new Bindable(new GameTypeTimeshift()); + + [JsonIgnore] + public Bindable MaxParticipants = new Bindable(); + + [JsonIgnore] + public Bindable> Participants = new Bindable>(Enumerable.Empty()); + [JsonProperty("duration")] private int duration { get => (int)Duration.Value.TotalMinutes; set => Duration.Value = TimeSpan.FromMinutes(value); } + // Todo: Find a better way to do this (https://github.com/ppy/osu-framework/issues/1930) [JsonProperty("max_attempts", DefaultValueHandling = DefaultValueHandling.Ignore)] private int? maxAttempts @@ -49,12 +60,6 @@ namespace osu.Game.Online.Multiplayer set => MaxAttempts.Value = value; } - public Bindable Status = new Bindable(new RoomStatusOpen()); - public Bindable Availability = new Bindable(); - public Bindable Type = new Bindable(new GameTypeTimeshift()); - public Bindable MaxParticipants = new Bindable(); - public Bindable> Participants = new Bindable>(Enumerable.Empty()); - public void CopyFrom(Room other) { RoomID.Value = other.RoomID; @@ -69,92 +74,8 @@ namespace osu.Game.Online.Multiplayer Playlist.Clear(); Playlist.AddRange(other.Playlist); } - } - public class PlaylistItem - { - [JsonProperty("id")] - public int ID { get; set; } - - [JsonProperty("beatmap")] - private APIBeatmap apiBeatmap { get; set; } - - public bool ShouldSerializeapiBeatmap() => false; - - private BeatmapInfo beatmap; - - [JsonIgnore] - public BeatmapInfo Beatmap - { - get => beatmap; - set - { - beatmap = value; - BeatmapID = value?.OnlineBeatmapID ?? 0; - } - } - - [JsonProperty("beatmap_id")] - public int BeatmapID { get; set; } - - [JsonProperty("ruleset_id")] - public int RulesetID { get; set; } - - [JsonIgnore] - public readonly BindableCollection AllowedMods = new BindableCollection(); - - [JsonIgnore] - public readonly BindableCollection RequiredMods = new BindableCollection(); - - private APIMod[] _allowedMods; - - [JsonProperty("allowed_mods")] - private APIMod[] allowedMods - { - get => AllowedMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray(); - set => _allowedMods = value; - } - - private APIMod[] _requiredMods; - - [JsonProperty("required_mods")] - private APIMod[] requiredMods - { - get => RequiredMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray(); - set => _requiredMods = value; - } - - [JsonIgnore] - public RulesetInfo Ruleset { get; set; } - - public void MapObjects(BeatmapManager beatmaps, RulesetStore rulesets) - { - // If we don't have an api beatmap, the request occurred as a result of room creation, so we can query the local beatmap instead - // Todo: Is this a bug? - Beatmap = apiBeatmap == null ? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == BeatmapID) : apiBeatmap.ToBeatmap(rulesets); - Ruleset = rulesets.GetRuleset(RulesetID); - - if (_allowedMods != null) - { - AllowedMods.Clear(); - AllowedMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => _allowedMods.Any(m => m.Acronym == mod.Acronym))); - - _allowedMods = null; - } - - if (_requiredMods != null) - { - RequiredMods.Clear(); - RequiredMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => _requiredMods.Any(m => m.Acronym == mod.Acronym))); - - _requiredMods = null; - } - } - - // Todo: Move this elsewhere for reusability - private class APIMod : IMod - { - public string Acronym { get; set; } - } + public bool ShouldSerializeRoomID() => false; + public bool ShouldSerializeHost() => false; } } From 8d640cdc25e50141dfeb49294c6c36060384d259 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 12:56:16 +0900 Subject: [PATCH 069/220] Fix leaderboard not being refreshed when finishing gameplay --- osu.Game.Tests/Visual/TestCaseMultiHeader.cs | 2 +- osu.Game/Screens/Multi/Lounge/LoungeScreen.cs | 10 +++++++--- osu.Game/Screens/Multi/Match/MatchScreen.cs | 20 ++++++++----------- osu.Game/Screens/Multi/Multiplayer.cs | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMultiHeader.cs b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs index e416000f31..deb098e97d 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiHeader.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual LoungeScreen loungeScreen; Children = new Drawable[] { - loungeScreen = new LoungeScreen + loungeScreen = new LoungeScreen(null) { Padding = new MarginPadding { Top = Header.HEIGHT }, }, diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index 1b49e0c1b3..f7dfd73b85 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -20,6 +21,7 @@ namespace osu.Game.Screens.Multi.Lounge private readonly Container content; private readonly SearchContainer search; private readonly RoomsContainer rooms; + private readonly Action pushGameplayScreen; [Cached] private readonly RoomManager manager; @@ -28,8 +30,10 @@ namespace osu.Game.Screens.Multi.Lounge protected override Drawable TransitionContent => content; - public LoungeScreen() + public LoungeScreen(Action pushGameplayScreen) { + this.pushGameplayScreen = pushGameplayScreen; + RoomInspector inspector; Children = new Drawable[] @@ -122,7 +126,7 @@ namespace osu.Game.Screens.Multi.Lounge if (Filter.Tabs.Current.Value == LoungeTab.Create) { Filter.Tabs.Current.Value = LoungeTab.Public; - Push(new MatchScreen(new Room())); + openRoom(new Room()); } search.SearchTerm = Filter.Search.Current.Value ?? string.Empty; @@ -136,7 +140,7 @@ namespace osu.Game.Screens.Multi.Lounge if (!IsCurrentScreen) return; - Push(new MatchScreen(room)); + Push(new MatchScreen(room, s => pushGameplayScreen?.Invoke(s))); } } } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 812f20f377..3f976cb9e2 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; @@ -43,22 +44,21 @@ namespace osu.Game.Screens.Multi.Match private readonly Components.Header header; private readonly Info info; private readonly MatchLeaderboard leaderboard; + private readonly Action pushGameplayScreen; [Cached] private readonly Room room; - [Resolved] - private Multiplayer multiplayer { get; set; } - [Resolved] private BeatmapManager beatmapManager { get; set; } [Resolved] private APIAccess api { get; set; } - public MatchScreen(Room room) + public MatchScreen(Room room, Action pushGameplayScreen) { this.room = room; + this.pushGameplayScreen = pushGameplayScreen; nameBind.BindTo(room.Name); statusBind.BindTo(room.Status); @@ -146,13 +146,6 @@ namespace osu.Game.Screens.Multi.Match playlistBind.BindTo(room.Playlist); } - protected override void OnResuming(Screen last) - { - base.OnResuming(last); - - leaderboard.RefreshScores(); - } - private void addPlaylistItem(PlaylistItem item) { playlistBind.Clear(); @@ -192,7 +185,10 @@ namespace osu.Game.Screens.Multi.Match { default: case GameTypeTimeshift _: - multiplayer.Push(new PlayerLoader(new TimeshiftPlayer(room.RoomID.Value ?? 0, room.Playlist.First().ID))); + var player = new TimeshiftPlayer(room.RoomID.Value ?? 0, room.Playlist.First().ID); + player.Exited += _ => leaderboard.RefreshScores(); + + pushGameplayScreen?.Invoke(new PlayerLoader(player)); break; } } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 0169d32c75..73a27a2b0a 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Multi { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Header.HEIGHT }, - Child = loungeScreen = new LoungeScreen(), + Child = loungeScreen = new LoungeScreen(Push), }, new Header(loungeScreen) }); From 5a8b255bd84661ee25a42156577dce158cdfe31c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 14:17:20 +0900 Subject: [PATCH 070/220] Directly bypass beatmap/ruleset restrictions --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 25 +++++++++++---------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 3f976cb9e2..3547534dfb 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -32,10 +32,9 @@ namespace osu.Game.Screens.Multi.Match private readonly Bindable> participantsBind = new Bindable>(); private readonly BindableCollection playlistBind = new BindableCollection(); - protected override Drawable TransitionContent => participants; + public override bool AllowBeatmapRulesetChange => false; - public override bool AllowBeatmapRulesetChange => allowBeatmapRulesetChange; - private bool allowBeatmapRulesetChange; + protected override Drawable TransitionContent => participants; public override string Title => room.Name.Value; @@ -164,19 +163,21 @@ namespace osu.Game.Screens.Multi.Match info.Beatmap.Value = item.Beatmap; info.Mods.Value = item.RequiredMods; - allowBeatmapRulesetChange = true; - // Todo: item.Beatmap can be null here... var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.BeatmapID) ?? item.Beatmap; - Schedule(() => - { - Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); - Beatmap.Value.Mods.Value = item.RequiredMods.ToArray(); - Ruleset.Value = item.Ruleset; + // Bypass any beatmap and ruleset restrictions + var beatmapDisabled = Beatmap.Disabled; + var rulesetDisabled = Ruleset.Disabled; + Beatmap.Disabled = false; + Ruleset.Disabled = false; - allowBeatmapRulesetChange = false; - }); + Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); + Beatmap.Value.Mods.Value = item.RequiredMods.ToArray(); + Ruleset.Value = item.Ruleset; + + Beatmap.Disabled = beatmapDisabled; + Ruleset.Disabled = rulesetDisabled; } private void onStart() From 2f15d100298b69bfe726c2c1a6ef0440b343abb6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 14:45:35 +0900 Subject: [PATCH 071/220] Play track while in the multiplayer lobby --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 3547534dfb..4c09c59804 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -178,6 +178,10 @@ namespace osu.Game.Screens.Multi.Match Beatmap.Disabled = beatmapDisabled; Ruleset.Disabled = rulesetDisabled; + + Beatmap.Value.Track.Looping = true; + Beatmap.Value.Track.Seek(Beatmap.Value.Metadata.PreviewTime); + Beatmap.Value.Track.Start(); } private void onStart() From aabe6c68f54b181b4a81024280d75364b0b7df9f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 17:07:47 +0900 Subject: [PATCH 072/220] Fix looping not working --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 4 --- osu.Game/Screens/Multi/Multiplayer.cs | 34 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 4c09c59804..3547534dfb 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -178,10 +178,6 @@ namespace osu.Game.Screens.Multi.Match Beatmap.Disabled = beatmapDisabled; Ruleset.Disabled = rulesetDisabled; - - Beatmap.Value.Track.Looping = true; - Beatmap.Value.Track.Seek(Beatmap.Value.Metadata.PreviewTime); - Beatmap.Value.Track.Start(); } private void onStart() diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 73a27a2b0a..0d618464b5 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -11,6 +11,7 @@ using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Screens.Menu; using osu.Game.Screens.Multi.Lounge; +using osu.Game.Screens.Multi.Match; namespace osu.Game.Screens.Multi { @@ -76,6 +77,11 @@ namespace osu.Game.Screens.Multi protected override bool OnExiting(Screen next) { waves.Hide(); + + var track = Beatmap.Value.Track; + if (track != null) + track.Looping = false; + return base.OnExiting(next); } @@ -102,6 +108,27 @@ namespace osu.Game.Screens.Multi base.LogoExiting(logo); } + protected override void Update() + { + base.Update(); + + if (currentScreen is MatchScreen) + { + var track = Beatmap.Value.Track; + if (track != null) + { + track.Looping = true; + + if (!track.IsRunning) + { + Game.Audio.AddItemToList(track); + track.Seek(Beatmap.Value.Metadata.PreviewTime); + track.Start(); + } + } + } + } + private void screenAdded(Screen newScreen) { currentScreen = (OsuScreen)newScreen; @@ -112,6 +139,13 @@ namespace osu.Game.Screens.Multi private void screenRemoved(Screen newScreen) { + if (currentScreen is MatchScreen) + { + var track = Beatmap.Value.Track; + if (track != null) + track.Looping = false; + } + currentScreen = (OsuScreen)newScreen; } From e4e1bde5dae2f6f14066696f206d4393801141ac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 17:08:02 +0900 Subject: [PATCH 073/220] Fix playlist events running too early Screens are async loaded --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 3547534dfb..ae6e4c7ff9 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -139,9 +139,10 @@ namespace osu.Game.Screens.Multi.Match playlistBind.ItemsRemoved += _ => setFromPlaylist(); } - [BackgroundDependencyLoader] - private void load() + protected override void LoadComplete() { + base.LoadComplete(); + playlistBind.BindTo(room.Playlist); } From 3cdeeb7ac5d156ce3c15f67142872cd858373289 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 18:09:46 +0900 Subject: [PATCH 074/220] Add forceful set helper methods in OsuGame --- osu.Game/OsuGame.cs | 26 +++++++++++++++++++++ osu.Game/Screens/Multi/Match/MatchScreen.cs | 18 ++++++-------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 31a00e68ac..51520a1606 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -671,6 +671,32 @@ namespace osu.Game MenuCursorContainer.CanShowCursor = currentScreen?.CursorVisible ?? false; } + /// + /// Sets while ignoring any beatmap. + /// + /// The beatmap to set. + public void ForcefullySetBeatmap(WorkingBeatmap beatmap) + { + var beatmapDisabled = Beatmap.Disabled; + + Beatmap.Disabled = false; + Beatmap.Value = beatmap; + Beatmap.Disabled = beatmapDisabled; + } + + /// + /// Sets while ignoring any ruleset restrictions. + /// + /// The beatmap to set. + public void ForcefullySetRuleset(RulesetInfo ruleset) + { + var rulesetDisabled = this.ruleset.Disabled; + + this.ruleset.Disabled = false; + this.ruleset.Value = ruleset; + this.ruleset.Disabled = rulesetDisabled; + } + private void screenAdded(Screen newScreen) { currentScreen = (OsuScreen)newScreen; diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index ae6e4c7ff9..da160b985c 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -54,6 +54,9 @@ namespace osu.Game.Screens.Multi.Match [Resolved] private APIAccess api { get; set; } + [Resolved] + private OsuGame game { get; set; } + public MatchScreen(Room room, Action pushGameplayScreen) { this.room = room; @@ -167,18 +170,11 @@ namespace osu.Game.Screens.Multi.Match // Todo: item.Beatmap can be null here... var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.BeatmapID) ?? item.Beatmap; - // Bypass any beatmap and ruleset restrictions - var beatmapDisabled = Beatmap.Disabled; - var rulesetDisabled = Ruleset.Disabled; - Beatmap.Disabled = false; - Ruleset.Disabled = false; + var newBeatmap = beatmapManager.GetWorkingBeatmap(localBeatmap); + newBeatmap.Mods.Value = item.RequiredMods.ToArray(); - Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); - Beatmap.Value.Mods.Value = item.RequiredMods.ToArray(); - Ruleset.Value = item.Ruleset; - - Beatmap.Disabled = beatmapDisabled; - Ruleset.Disabled = rulesetDisabled; + game.ForcefullySetBeatmap(newBeatmap); + game.ForcefullySetRuleset(item.Ruleset); } private void onStart() From 4050cb88ea476cce8bf0363d0f9a4c6d9f63e523 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 18:09:54 +0900 Subject: [PATCH 075/220] Fix potential nullref --- osu.Game/Screens/Multi/Match/Components/ReadyButton.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index c52a3be7cb..61ea7cb8fa 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -54,7 +54,8 @@ namespace osu.Game.Screens.Multi.Match.Components { base.Dispose(isDisposing); - beatmaps.ItemAdded -= beatmapAdded; + if (beatmaps != null) + beatmaps.ItemAdded -= beatmapAdded; } } } From 72d1ba897fba0801cfe795247088254f2f145ab9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 18:29:13 +0900 Subject: [PATCH 076/220] Reorder tabs --- osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs b/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs index fa760c97e3..538dcc341e 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs @@ -21,8 +21,8 @@ namespace osu.Game.Screens.Multi.Match.Components public MatchTabControl() { - AddItem(new SettingsMatchPage()); AddItem(new RoomMatchPage()); + AddItem(new SettingsMatchPage()); } [BackgroundDependencyLoader] From 1051584f0f6972094735566a82aab9dd1bd5cf3e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 10:51:54 +0900 Subject: [PATCH 077/220] Fix room duration not being set --- osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index a7149fbb6d..d3098efb82 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -237,6 +237,8 @@ namespace osu.Game.Screens.Multi.Match.Components else maxParticipantsBind.Value = null; + durationBind.Value = DurationField.Current.Value; + manager?.CreateRoom(room); } From 2c000a9a1d51d14e389bda0fd498566acb15620b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 10:52:15 +0900 Subject: [PATCH 078/220] Disallow starting gameplay if there's not enough time in the room --- osu.Game.Tests/Visual/TestCaseMatchInfo.cs | 2 +- osu.Game/Online/Multiplayer/Room.cs | 6 +++ .../Screens/Multi/Match/Components/Info.cs | 4 +- .../Multi/Match/Components/ReadyButton.cs | 49 +++++++++++++++---- osu.Game/Screens/Multi/Match/MatchScreen.cs | 2 +- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs index 0272581a8f..799b5f2526 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - Info info = new Info(); + Info info = new Info(new Room()); Add(info); AddStep(@"set name", () => info.Name.Value = @"Room Name?"); diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index ed85e6c31c..5249870e35 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -52,6 +52,10 @@ namespace osu.Game.Online.Multiplayer set => Duration.Value = TimeSpan.FromMinutes(value); } + // Only supports retrieval for now + [JsonProperty("ends_at")] + public Bindable EndDate = new Bindable(); + // Todo: Find a better way to do this (https://github.com/ppy/osu-framework/issues/1930) [JsonProperty("max_attempts", DefaultValueHandling = DefaultValueHandling.Ignore)] private int? maxAttempts @@ -70,6 +74,7 @@ namespace osu.Game.Online.Multiplayer Type.Value = other.Type; MaxParticipants.Value = other.MaxParticipants; Participants.Value = other.Participants.Value.ToArray(); + EndDate = other.EndDate; Playlist.Clear(); Playlist.AddRange(other.Playlist); @@ -77,5 +82,6 @@ namespace osu.Game.Online.Multiplayer public bool ShouldSerializeRoomID() => false; public bool ShouldSerializeHost() => false; + public bool ShouldSerializeEndDate() => false; } } diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index 1750323486..77295a1a13 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Multi.Match.Components public readonly Bindable Type = new Bindable(); public readonly Bindable> Mods = new Bindable>(); - public Info() + public Info(Room room) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -106,7 +106,7 @@ namespace osu.Game.Screens.Multi.Match.Components Children = new Drawable[] { viewBeatmapButton = new ViewBeatmapButton(), - readyButton = new ReadyButton + readyButton = new ReadyButton(room) { Action = () => OnStart?.Invoke() } diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index 61ea7cb8fa..d3726da246 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -1,11 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; using osuTK; namespace osu.Game.Screens.Multi.Match.Components @@ -14,11 +16,19 @@ namespace osu.Game.Screens.Multi.Match.Components { public readonly IBindable Beatmap = new Bindable(); + private readonly Room room; + + [Resolved] + private IBindableBeatmap gameBeatmap { get; set; } + [Resolved] private BeatmapManager beatmaps { get; set; } - public ReadyButton() + private bool hasBeatmap; + + public ReadyButton(Room room) { + this.room = room; RelativeSizeAxes = Axes.Y; Size = new Vector2(200, 1); @@ -30,24 +40,43 @@ namespace osu.Game.Screens.Multi.Match.Components { beatmaps.ItemAdded += beatmapAdded; - Beatmap.BindValueChanged(updateEnabledState, true); + Beatmap.BindValueChanged(updateBeatmap, true); } - private void updateEnabledState(BeatmapInfo beatmap) + private void updateBeatmap(BeatmapInfo beatmap) { - if (beatmap?.OnlineBeatmapID == null) - { - Enabled.Value = false; - return; - } + hasBeatmap = false; - Enabled.Value = beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID) != null; + if (beatmap?.OnlineBeatmapID == null) + return; + + hasBeatmap = beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID) != null; } private void beatmapAdded(BeatmapSetInfo model, bool existing, bool silent) { if (model.Beatmaps.Any(b => b.OnlineBeatmapID == Beatmap.Value.OnlineBeatmapID)) - Schedule(() => Enabled.Value = true); + Schedule(() => hasBeatmap = true); + } + + protected override void Update() + { + base.Update(); + + updateEnabledState(); + } + + private void updateEnabledState() + { + if (gameBeatmap.Value == null) + { + Enabled.Value = false; + return; + } + + bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(gameBeatmap.Value.Track.Length) < room.EndDate; + + Enabled.Value = hasBeatmap && hasEnoughTime; } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index da160b985c..7a21a2339a 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -79,7 +79,7 @@ namespace osu.Game.Screens.Multi.Match Content = new[] { new Drawable[] { header = new Components.Header { Depth = -1 } }, - new Drawable[] { info = new Info { OnStart = onStart } }, + new Drawable[] { info = new Info(room) { OnStart = onStart } }, new Drawable[] { new GridContainer From b89a6bea4c4a710bf87ca7a2c95d5872d1e45333 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 12:44:51 +0900 Subject: [PATCH 079/220] Make DrawableDate adjustable --- osu.Game/Graphics/DrawableDate.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 28f8bdf82f..639a549936 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -4,6 +4,7 @@ using System; using Humanizer; using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.Sprites; @@ -11,13 +12,27 @@ namespace osu.Game.Graphics { public class DrawableDate : OsuSpriteText, IHasTooltip { - protected readonly DateTimeOffset Date; + private DateTimeOffset date; + + public DateTimeOffset Date + { + get => date; + set + { + if (date == value) + return; + date = value.ToLocalTime(); + + if (LoadState >= LoadState.Ready) + updateTime(); + } + } public DrawableDate(DateTimeOffset date) { Font = "Exo2.0-RegularItalic"; - Date = date.ToLocalTime(); + Date = date; } [BackgroundDependencyLoader] From 224e644aa1eee1ab23241ab4835198fb7b28e5fe Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 13:07:43 +0900 Subject: [PATCH 080/220] Fix negative dates, and time moving in opposite direction --- osu.Game/Graphics/DrawableDate.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 639a549936..87711c72c7 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -54,14 +54,14 @@ namespace osu.Game.Graphics var diffToNow = DateTimeOffset.Now.Subtract(Date); double timeUntilNextUpdate = 1000; - if (diffToNow.TotalSeconds > 60) + if (Math.Abs(diffToNow.TotalSeconds) > 120) { timeUntilNextUpdate *= 60; - if (diffToNow.TotalMinutes > 60) + if (Math.Abs(diffToNow.TotalMinutes) > 120) { timeUntilNextUpdate *= 60; - if (diffToNow.TotalHours > 24) + if (Math.Abs(diffToNow.TotalHours) > 48) timeUntilNextUpdate *= 24; } } From a8d88dea3b26c1d33f6f6571e7c33a3634b36783 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 13:07:56 +0900 Subject: [PATCH 081/220] Display time remaining in the room --- osu.Game/Online/Multiplayer/Room.cs | 2 +- .../Screens/Multi/Match/Components/Info.cs | 28 +++++++++++++++++++ osu.Game/Screens/Multi/Match/MatchScreen.cs | 3 ++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 5249870e35..39319aa32e 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -74,7 +74,7 @@ namespace osu.Game.Online.Multiplayer Type.Value = other.Type; MaxParticipants.Value = other.MaxParticipants; Participants.Value = other.Participants.Value.ToArray(); - EndDate = other.EndDate; + EndDate.Value = other.EndDate; Playlist.Clear(); Playlist.AddRange(other.Playlist); diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index 77295a1a13..9710f4b2fd 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -35,6 +35,7 @@ namespace osu.Game.Screens.Multi.Match.Components public readonly Bindable Beatmap = new Bindable(); public readonly Bindable Type = new Bindable(); public readonly Bindable> Mods = new Bindable>(); + public readonly Bindable EndDate = new Bindable(); public Info(Room room) { @@ -46,6 +47,7 @@ namespace osu.Game.Screens.Multi.Match.Components BeatmapTypeInfo beatmapTypeInfo; OsuSpriteText name; ModDisplay modDisplay; + DrawableDate date; Children = new Drawable[] { @@ -77,6 +79,7 @@ namespace osu.Game.Screens.Multi.Match.Components { name = new OsuSpriteText { TextSize = 30 }, availabilityStatus = new OsuSpriteText { TextSize = 14 }, + date = new MatchDate { TextSize = 14 } } }, new FillFlowContainer @@ -126,6 +129,7 @@ namespace osu.Game.Screens.Multi.Match.Components Availability.BindValueChanged(_ => updateAvailabilityStatus()); Status.BindValueChanged(_ => updateAvailabilityStatus()); Name.BindValueChanged(n => name.Text = n); + EndDate.BindValueChanged(d => date.Date = d); } [BackgroundDependencyLoader] @@ -152,5 +156,29 @@ namespace osu.Game.Screens.Multi.Match.Components availabilityStatus.Text = $"{Availability.Value.GetDescription()}, {Status.Value.Message}"; } } + + private class MatchDate : DrawableDate + { + public MatchDate() + : base(DateTimeOffset.UtcNow) + { + } + + protected override string Format() + { + var diffToNow = Date.Subtract(DateTimeOffset.Now); + + if (diffToNow.TotalSeconds < -5) + return $"Closed {base.Format()}"; + + if (diffToNow.TotalSeconds < 0) + return "Closed"; + + if (diffToNow.TotalSeconds < 5) + return "Closing soon"; + + return $"Closing {base.Format()}"; + } + } } } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 7a21a2339a..c169a5fb5d 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -31,6 +31,7 @@ namespace osu.Game.Screens.Multi.Match private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); private readonly BindableCollection playlistBind = new BindableCollection(); + private readonly Bindable endDateBind = new Bindable(); public override bool AllowBeatmapRulesetChange => false; @@ -68,6 +69,7 @@ namespace osu.Game.Screens.Multi.Match typeBind.BindTo(room.Type); participantsBind.BindTo(room.Participants); maxParticipantsBind.BindTo(room.MaxParticipants); + endDateBind.BindTo(room.EndDate); RoomSettingsOverlay settings; @@ -134,6 +136,7 @@ namespace osu.Game.Screens.Multi.Match info.Status.BindTo(statusBind); info.Availability.BindTo(availabilityBind); info.Type.BindTo(typeBind); + info.EndDate.BindTo(endDateBind); participants.Users.BindTo(participantsBind); participants.MaxParticipants.BindTo(maxParticipantsBind); From c544a5b9f0ad7afbfc7a5765111d9993f31a9ac2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 15:20:23 +0900 Subject: [PATCH 082/220] Add end date to the drawable room too --- .../Screens/Multi/Components/EndDateInfo.cs | 32 +++++++++++++++++++ .../Multi/Lounge/Components/DrawableRoom.cs | 30 +++++++++++++---- .../Screens/Multi/Match/Components/Info.cs | 30 ++--------------- 3 files changed, 59 insertions(+), 33 deletions(-) create mode 100644 osu.Game/Screens/Multi/Components/EndDateInfo.cs diff --git a/osu.Game/Screens/Multi/Components/EndDateInfo.cs b/osu.Game/Screens/Multi/Components/EndDateInfo.cs new file mode 100644 index 0000000000..c71ec04d33 --- /dev/null +++ b/osu.Game/Screens/Multi/Components/EndDateInfo.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Multi.Components +{ + public class EndDateInfo : DrawableDate + { + public EndDateInfo() + : base(DateTimeOffset.UtcNow) + { + } + + protected override string Format() + { + var diffToNow = Date.Subtract(DateTimeOffset.Now); + + if (diffToNow.TotalSeconds < -5) + return $"Closed {base.Format()}"; + + if (diffToNow.TotalSeconds < 0) + return "Closed"; + + if (diffToNow.TotalSeconds < 5) + return "Closing soon"; + + return $"Closing {base.Format()}"; + } + } +} diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index 5cf11e5c98..adcb088f4e 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components private const float corner_radius = 5; private const float transition_duration = 60; private const float content_padding = 10; - private const float height = 100; + private const float height = 110; private const float side_strip_width = 5; private const float cover_width = 145; @@ -45,6 +45,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components private readonly Bindable typeBind = new Bindable(); private readonly Bindable> participantsBind = new Bindable>(); private readonly IBindableCollection playlistBind = new BindableCollection(); + private readonly IBindable endDateBind = new Bindable(); private readonly Bindable beatmap = new Bindable(); @@ -111,8 +112,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components Box sideStrip; OsuSpriteText status; ParticipantInfo participantInfo; - OsuSpriteText name; + EndDateInfo endDate; Children = new Drawable[] { @@ -189,11 +190,25 @@ namespace osu.Game.Screens.Multi.Lounge.Components TextSize = 14, Font = @"Exo2.0-Bold", }, - beatmapTitle = new BeatmapTitle + new FillFlowContainer { - TextSize = 14, - Colour = colours.Gray9 - }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new Drawable[] + { + endDate = new EndDateInfo + { + TextSize = 14, + }, + beatmapTitle = new BeatmapTitle + { + TextSize = 14, + Colour = colours.Gray9 + }, + } + } }, }, modeTypeInfo = new ModeTypeInfo @@ -224,6 +239,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components typeBind.BindTo(Room.Type); playlistBind.BindTo(Room.Playlist); participantsBind.BindTo(Room.Participants); + endDateBind.BindTo(Room.EndDate); + + endDateBind.BindValueChanged(d => endDate.Date = d, true); modeTypeInfo.Type.BindTo(typeBind); diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index 9710f4b2fd..f63135fc2d 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -47,7 +47,7 @@ namespace osu.Game.Screens.Multi.Match.Components BeatmapTypeInfo beatmapTypeInfo; OsuSpriteText name; ModDisplay modDisplay; - DrawableDate date; + EndDateInfo endDate; Children = new Drawable[] { @@ -79,7 +79,7 @@ namespace osu.Game.Screens.Multi.Match.Components { name = new OsuSpriteText { TextSize = 30 }, availabilityStatus = new OsuSpriteText { TextSize = 14 }, - date = new MatchDate { TextSize = 14 } + endDate = new EndDateInfo { TextSize = 14 } } }, new FillFlowContainer @@ -129,7 +129,7 @@ namespace osu.Game.Screens.Multi.Match.Components Availability.BindValueChanged(_ => updateAvailabilityStatus()); Status.BindValueChanged(_ => updateAvailabilityStatus()); Name.BindValueChanged(n => name.Text = n); - EndDate.BindValueChanged(d => date.Date = d); + EndDate.BindValueChanged(d => endDate.Date = d); } [BackgroundDependencyLoader] @@ -156,29 +156,5 @@ namespace osu.Game.Screens.Multi.Match.Components availabilityStatus.Text = $"{Availability.Value.GetDescription()}, {Status.Value.Message}"; } } - - private class MatchDate : DrawableDate - { - public MatchDate() - : base(DateTimeOffset.UtcNow) - { - } - - protected override string Format() - { - var diffToNow = Date.Subtract(DateTimeOffset.Now); - - if (diffToNow.TotalSeconds < -5) - return $"Closed {base.Format()}"; - - if (diffToNow.TotalSeconds < 0) - return "Closed"; - - if (diffToNow.TotalSeconds < 5) - return "Closing soon"; - - return $"Closing {base.Format()}"; - } - } } } From 673082445e5470db0e0ed21c8b00c33947d008c3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 16:56:51 +0900 Subject: [PATCH 083/220] Rework filtering --- .../Multi/Lounge/Components/FilterControl.cs | 39 +++++++++---------- .../Multi/Lounge/Components/FilterCriteria.cs | 6 +-- .../Multi/Lounge/Components/RoomsContainer.cs | 21 +++++++++- osu.Game/Screens/Multi/Lounge/LoungeScreen.cs | 20 ++-------- osu.Game/Screens/Multi/Multiplayer.cs | 26 ++++++++++++- 5 files changed, 70 insertions(+), 42 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs index ddab9c197e..01bc23ba4b 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs @@ -1,45 +1,42 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.ComponentModel; using osu.Game.Graphics; -using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; using osuTK.Graphics; namespace osu.Game.Screens.Multi.Lounge.Components { - public class FilterControl : SearchableListFilterControl + public class FilterControl : SearchableListFilterControl { protected override Color4 BackgroundColour => OsuColour.FromHex(@"362e42"); - protected override LoungeTab DefaultTab => LoungeTab.Public; + protected override PrimaryFilter DefaultTab => PrimaryFilter.Current; public FilterControl() { DisplayStyleControl.Hide(); } - public FilterCriteria CreateCriteria() => new FilterCriteria { Availability = availability }; - - private RoomAvailability availability + public FilterCriteria CreateCriteria() => new FilterCriteria { - get - { - switch (Tabs.Current.Value) - { - default: - case LoungeTab.Public: - return RoomAvailability.Public; - case LoungeTab.Private: - return RoomAvailability.FriendsOnly; - } - } - } + SearchString = Search.Current.Value ?? string.Empty, + PrimaryFilter = Tabs.Current, + SecondaryFilter = DisplayStyleControl.Dropdown.Current + }; } - public enum LoungeTab + public enum PrimaryFilter + { + Current, + [Description("Recently Ended")] + RecentlyEnded, + Participated, + } + + public enum SecondaryFilter { - Create, Public, - Private, + //Private, } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs index ec62ef1bdf..0a1c8a3e84 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs @@ -1,12 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Online.Multiplayer; - namespace osu.Game.Screens.Multi.Lounge.Components { public class FilterCriteria { - public RoomAvailability Availability; + public string SearchString; + public PrimaryFilter PrimaryFilter; + public SecondaryFilter SecondaryFilter; } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 072a892954..af66f5bfe8 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -59,7 +59,26 @@ namespace osu.Game.Screens.Multi.Lounge.Components public void Filter(FilterCriteria criteria) { - roomFlow.Children.ForEach(r => r.MatchingFilter = criteria == null || r.Room.Availability == criteria.Availability); + roomFlow.Children.ForEach(r => + { + if (criteria == null) + r.MatchingFilter = true; + else + { + bool matchingFilter = true; + matchingFilter &= r.FilterTerms.Any(term => term.IndexOf(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase) >= 0); + + switch (criteria.SecondaryFilter) + { + default: + case SecondaryFilter.Public: + r.MatchingFilter = r.Room.Availability.Value == RoomAvailability.Public; + break; + } + + r.MatchingFilter = matchingFilter; + } + }); currentFilter = criteria; } diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index f7dfd73b85..81a478b778 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -19,7 +19,6 @@ namespace osu.Game.Screens.Multi.Lounge protected readonly FilterControl Filter; private readonly Container content; - private readonly SearchContainer search; private readonly RoomsContainer rooms; private readonly Action pushGameplayScreen; @@ -53,11 +52,11 @@ namespace osu.Game.Screens.Multi.Lounge Vertical = 35 - DrawableRoom.SELECTION_BORDER_WIDTH, Right = 20 - DrawableRoom.SELECTION_BORDER_WIDTH }, - Child = search = new SearchContainer + Child = new SearchContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = rooms = new RoomsContainer { OpenRequested = openRoom } + Child = rooms = new RoomsContainer { OpenRequested = Open } }, }, inspector = new RoomInspector @@ -121,20 +120,9 @@ namespace osu.Game.Screens.Multi.Lounge Filter.Search.HoldFocus = false; } - private void filterRooms() - { - if (Filter.Tabs.Current.Value == LoungeTab.Create) - { - Filter.Tabs.Current.Value = LoungeTab.Public; - openRoom(new Room()); - } + private void filterRooms() => rooms.Filter(Filter.CreateCriteria()); - search.SearchTerm = Filter.Search.Current.Value ?? string.Empty; - - rooms.Filter(Filter.CreateCriteria()); - } - - private void openRoom(Room room) + public void Open(Room room) { // Handles the case where a room is clicked 3 times in quick succession if (!IsCurrentScreen) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 0d618464b5..4a0fa141c8 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -9,9 +9,13 @@ using osu.Framework.Screens; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Multiplayer; +using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Screens.Menu; using osu.Game.Screens.Multi.Lounge; using osu.Game.Screens.Multi.Match; +using osuTK; namespace osu.Game.Screens.Multi { @@ -22,6 +26,8 @@ namespace osu.Game.Screens.Multi public override bool AllowBeatmapRulesetChange => currentScreen?.AllowBeatmapRulesetChange ?? base.AllowBeatmapRulesetChange; + private readonly OsuButton createButton; + private OsuScreen currentScreen; public Multiplayer() @@ -60,7 +66,21 @@ namespace osu.Game.Screens.Multi Padding = new MarginPadding { Top = Header.HEIGHT }, Child = loungeScreen = new LoungeScreen(Push), }, - new Header(loungeScreen) + new Header(loungeScreen), + createButton = new HeaderButton + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.None, + Size = new Vector2(150, Header.HEIGHT - 20), + Margin = new MarginPadding + { + Top = 10, + Right = 10, + }, + Text = "Create room", + Action = () => loungeScreen.Open(new Room()) + } }); screenAdded(loungeScreen); @@ -126,7 +146,11 @@ namespace osu.Game.Screens.Multi track.Start(); } } + + createButton.Hide(); } + else + createButton.Show(); } private void screenAdded(Screen newScreen) From c86d9533bd86049314d3fef74f7cfe4628e98c24 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 18:01:21 +0900 Subject: [PATCH 084/220] Add PollImmediately() --- osu.Game/Online/PollingComponent.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/PollingComponent.cs b/osu.Game/Online/PollingComponent.cs index d9dcfc40c2..7e5ed31491 100644 --- a/osu.Game/Online/PollingComponent.cs +++ b/osu.Game/Online/PollingComponent.cs @@ -77,13 +77,22 @@ namespace osu.Game.Online } /// - /// Perform the polling in this method. Call when done. + /// Performs a poll. Implement but do not call this. /// protected virtual Task Poll() { return Task.CompletedTask; } + /// + /// Immediately performs a . + /// + public void PollImmediately() + { + lastTimePolled = Time.Current - timeBetweenPolls; + scheduleNextPoll(); + } + /// /// Call when a poll operation has completed. /// From 36f6b4fc3fe530adf191f8b3239d1b961fe2dcc7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 18:02:05 +0900 Subject: [PATCH 085/220] Hook up participated filter Very early stages, implementation will change. --- .../Multi/Lounge/Components/RoomsContainer.cs | 1 + osu.Game/Screens/Multi/Lounge/LoungeScreen.cs | 6 +++- osu.Game/Screens/Multi/RoomManager.cs | 36 ++++++++++++++++++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index af66f5bfe8..71d39cd270 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -79,6 +79,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components r.MatchingFilter = matchingFilter; } }); + currentFilter = criteria; } diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index 81a478b778..408c02f805 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -120,7 +120,11 @@ namespace osu.Game.Screens.Multi.Lounge Filter.Search.HoldFocus = false; } - private void filterRooms() => rooms.Filter(Filter.CreateCriteria()); + private void filterRooms() + { + rooms.Filter(Filter.CreateCriteria()); + manager.Filter(Filter.CreateCriteria()); + } public void Open(Room room) { diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 7e29aacaf4..7d3e4f5657 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -15,6 +15,7 @@ using osu.Game.Online; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; +using osu.Game.Screens.Multi.Lounge.Components; namespace osu.Game.Screens.Multi { @@ -25,6 +26,8 @@ namespace osu.Game.Screens.Multi public readonly Bindable Current = new Bindable(); + private FilterCriteria currentFilter = new FilterCriteria(); + [Resolved] private APIAccess api { get; set; } @@ -50,6 +53,12 @@ namespace osu.Game.Screens.Multi api.Queue(req); } + public void Filter(FilterCriteria criteria) + { + currentFilter = criteria; + PollImmediately(); + } + protected override Task Poll() { if (!api.IsLoggedIn) @@ -57,10 +66,18 @@ namespace osu.Game.Screens.Multi var tcs = new TaskCompletionSource(); - var pollReq = new GetRoomsRequest(); + var pollReq = new GetRoomsRequest(currentFilter.PrimaryFilter); pollReq.Success += result => { + // Remove past matches + foreach (var r in rooms.ToList()) + { + if (result.All(e => e.RoomID.Value != r.RoomID.Value)) + rooms.Remove(r); + } + + // Add new matches, or update existing foreach (var r in result) { processPlaylist(r); @@ -126,6 +143,23 @@ namespace osu.Game.Screens.Multi private class GetRoomsRequest : APIRequest> { + private readonly PrimaryFilter primaryFilter; + + public GetRoomsRequest(PrimaryFilter primaryFilter) + { + this.primaryFilter = primaryFilter; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + + if (primaryFilter == PrimaryFilter.Participated) + req.AddParameter("participated", "1"); + + return req; + } + protected override string Target => "rooms"; } } From 03546c9d0d25ceb6d450ce289d96a4376288a1ea Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 15:16:46 +0900 Subject: [PATCH 086/220] Implement primary filter routes --- .../Multi/Lounge/Components/FilterControl.cs | 5 ++-- osu.Game/Screens/Multi/RoomManager.cs | 27 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs index 01bc23ba4b..286a4c18b0 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components public class FilterControl : SearchableListFilterControl { protected override Color4 BackgroundColour => OsuColour.FromHex(@"362e42"); - protected override PrimaryFilter DefaultTab => PrimaryFilter.Current; + protected override PrimaryFilter DefaultTab => PrimaryFilter.Open; public FilterControl() { @@ -28,10 +28,11 @@ namespace osu.Game.Screens.Multi.Lounge.Components public enum PrimaryFilter { - Current, + Open, [Description("Recently Ended")] RecentlyEnded, Participated, + Owned, } public enum SecondaryFilter diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 7d3e4f5657..8e887e51e1 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -150,17 +150,30 @@ namespace osu.Game.Screens.Multi this.primaryFilter = primaryFilter; } - protected override WebRequest CreateWebRequest() + protected override string Target { - var req = base.CreateWebRequest(); + get + { + string target = "rooms"; - if (primaryFilter == PrimaryFilter.Participated) - req.AddParameter("participated", "1"); + switch (primaryFilter) + { + case PrimaryFilter.Open: + break; + case PrimaryFilter.Owned: + target += "/owned"; + break; + case PrimaryFilter.Participated: + target += "/participated"; + break; + case PrimaryFilter.RecentlyEnded: + target += "/ended"; + break; + } - return req; + return target; + } } - - protected override string Target => "rooms"; } } } From 72016a416b9f5be0ef14a929a39c6bd14d773cb8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 15:17:08 +0900 Subject: [PATCH 087/220] Deselect match if ended --- osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 71d39cd270..bde76a01df 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -99,6 +99,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components toRemove.Action = null; roomFlow.Remove(toRemove); + + if (currentRoom.Value == r) + currentRoom.Value = null; } } From 2e28f378deb2afbb1fa621bc506dedda2947b59f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 15:17:33 +0900 Subject: [PATCH 088/220] Move beatmap + mod info to header --- osu.Game.Tests/Visual/TestCaseMatchHeader.cs | 58 +++++++++++++++++ osu.Game.Tests/Visual/TestCaseMatchInfo.cs | 3 - .../UpdateableBeatmapBackgroundSprite.cs | 2 +- .../Screens/Multi/Components/BeatmapTitle.cs | 2 +- .../Multi/Components/BeatmapTypeInfo.cs | 6 +- .../Screens/Multi/Components/ModeTypeInfo.cs | 4 +- .../Multi/Lounge/Components/DrawableRoom.cs | 13 ++-- .../Multi/Lounge/Components/RoomInspector.cs | 11 ++-- .../Screens/Multi/Match/Components/Header.cs | 64 +++++++++++++------ .../Screens/Multi/Match/Components/Info.cs | 25 -------- .../Multi/Match/Components/MatchTabControl.cs | 8 +-- .../Match/Components/RoomSettingsOverlay.cs | 31 +++++++-- osu.Game/Screens/Multi/Match/MatchScreen.cs | 7 +- 13 files changed, 153 insertions(+), 81 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseMatchHeader.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchHeader.cs b/osu.Game.Tests/Visual/TestCaseMatchHeader.cs new file mode 100644 index 0000000000..8ff16a20b9 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMatchHeader.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Configuration; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Screens.Multi.Match.Components; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseMatchHeader : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(Header) + }; + + private readonly Bindable beatmap = new Bindable(); + private readonly Bindable type = new Bindable(); + private readonly Bindable> mods = new Bindable>(); + + public TestCaseMatchHeader() + { + var header = new Header(new Room()); + + header.Beatmap.BindTo(beatmap); + header.Type.BindTo(type); + header.Mods.BindTo(mods); + + beatmap.Value = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Title = "Title", + Artist = "Artist", + AuthorString = "Author", + }, + Version = "Version", + Ruleset = new OsuRuleset().RulesetInfo + }; + + type.Value = new GameTypeTimeshift(); + mods.Value = new Mod[] + { + new OsuModDoubleTime(), + new OsuModNoFail(), + new OsuModRelax(), + }; + + Child = header; + } + } +} diff --git a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs index 799b5f2526..0d3c769dc5 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs @@ -44,13 +44,10 @@ namespace osu.Game.Tests.Visual }, }); - AddStep(@"set type", () => info.Type.Value = new GameTypeTagTeam()); - AddStep(@"change name", () => info.Name.Value = @"Room Name!"); AddStep(@"change availability", () => info.Availability.Value = RoomAvailability.InviteOnly); AddStep(@"change status", () => info.Status.Value = new RoomStatusOpen()); AddStep(@"null beatmap", () => info.Beatmap.Value = null); - AddStep(@"change type", () => info.Type.Value = new GameTypeTeamVersus()); AddStep(@"change beatmap", () => info.Beatmap.Value = new BeatmapInfo { StarDifficulty = 4.2, diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 15b89d27bd..0a9726b121 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -11,7 +11,7 @@ namespace osu.Game.Beatmaps.Drawables { public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable { - public readonly Bindable Beatmap = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); [Resolved] private BeatmapManager beatmaps { get; set; } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index e3ef5eb401..02ec598f82 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Multi.Components set { beatmapTitle.TextSize = beatmapDash.TextSize = beatmapArtist.TextSize = value; } } - public readonly Bindable Beatmap = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); public BeatmapTitle() { diff --git a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs index 2bd7b19a0a..90319de40f 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs @@ -17,9 +17,9 @@ namespace osu.Game.Screens.Multi.Components { private readonly OsuSpriteText beatmapAuthor; - public readonly Bindable Beatmap = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); - public readonly Bindable Type = new Bindable(); + public readonly IBindable Type = new Bindable(); public BeatmapTypeInfo() { @@ -67,7 +67,7 @@ namespace osu.Game.Screens.Multi.Components [BackgroundDependencyLoader] private void load(OsuColour colours) { - beatmapAuthor.Colour = colours.Gray9; + beatmapAuthor.Colour = colours.GrayC; } } } diff --git a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 87d150c5a4..8104244084 100644 --- a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -18,8 +18,8 @@ namespace osu.Game.Screens.Multi.Components private readonly Container rulesetContainer; - public readonly Bindable Beatmap = new Bindable(); - public readonly Bindable Type = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); + public readonly IBindable Type = new Bindable(); public ModeTypeInfo() { diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index adcb088f4e..c1a9dd3b1d 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -47,7 +47,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components private readonly IBindableCollection playlistBind = new BindableCollection(); private readonly IBindable endDateBind = new Bindable(); - private readonly Bindable beatmap = new Bindable(); + private readonly Bindable beatmap = new Bindable(); private UpdateableBeatmapBackgroundSprite background; private BeatmapTitle beatmapTitle; @@ -243,6 +243,10 @@ namespace osu.Game.Screens.Multi.Lounge.Components endDateBind.BindValueChanged(d => endDate.Date = d, true); + background.Beatmap.BindTo(beatmap); + modeTypeInfo.Beatmap.BindTo(beatmap); + beatmapTitle.Beatmap.BindTo(beatmap); + modeTypeInfo.Type.BindTo(typeBind); participantInfo.Host.BindTo(hostBind); @@ -266,12 +270,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components return; // For now, only the first playlist item is supported - var item = playlistBind.First(); - - beatmap.Value = beatmaps.GetWorkingBeatmap(item.Beatmap); - background.Beatmap.Value = item.Beatmap; - modeTypeInfo.Beatmap.Value = item.Beatmap; - beatmapTitle.Beatmap.Value = item.Beatmap; + beatmap.Value = playlistBind.First().Beatmap; } } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 818fd78f32..80adc8787f 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components private readonly Bindable> participantsBind = new Bindable>(); private readonly IBindableCollection playlistBind = new BindableCollection(); - private readonly Bindable beatmap = new Bindable(); + private readonly Bindable beatmap = new Bindable(); private OsuColour colours; private Box statusStrip; @@ -190,6 +190,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components beatmapTypeInfo.Type.BindTo(typeBind); + background.Beatmap.BindTo(beatmap); + beatmapTypeInfo.Beatmap.BindTo(beatmap); + Room.BindValueChanged(updateRoom, true); } @@ -244,11 +247,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components return; // For now, only the first playlist item is supported - var item = playlistBind.First(); - - beatmap.Value = beatmaps.GetWorkingBeatmap(item.Beatmap); - background.Beatmap.Value = item.Beatmap; - beatmapTypeInfo.Beatmap.Value = item.Beatmap; + beatmap.Value = playlistBind.First().Beatmap; } protected override void UpdateAfterChildren() diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 4b831ed3c6..de93e8587f 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; @@ -14,6 +15,10 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; +using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Multi.Components; +using osu.Game.Screens.Play.HUD; +using osuTK; using osuTK.Graphics; namespace osu.Game.Screens.Multi.Match.Components @@ -23,6 +28,8 @@ namespace osu.Game.Screens.Multi.Match.Components public const float HEIGHT = 200; public readonly Bindable Beatmap = new Bindable(); + public readonly IBindable Type = new Bindable(); + public readonly Bindable> Mods = new Bindable>(); private readonly Box tabStrip; @@ -30,25 +37,31 @@ namespace osu.Game.Screens.Multi.Match.Components public Action OnRequestSelectBeatmap; - public Header() + public Header(Room room) { RelativeSizeAxes = Axes.X; Height = HEIGHT; + BeatmapTypeInfo beatmapTypeInfo; BeatmapSelectButton beatmapButton; UpdateableBeatmapBackgroundSprite background; + ModDisplay modDisplay; + Children = new Drawable[] { new Container { RelativeSizeAxes = Axes.Both, Masking = true, - Child = background = new HeaderBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both } - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Color4.Black.Opacity(0.5f)), + Children = new Drawable[] + { + background = new HeaderBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.4f), Color4.Black.Opacity(0.6f)), + }, + } }, tabStrip = new Box { @@ -60,9 +73,27 @@ namespace osu.Game.Screens.Multi.Match.Components new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + Padding = new MarginPadding + { + Left = SearchableListOverlay.WIDTH_PADDING, + Top = 20 + }, Children = new Drawable[] { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + beatmapTypeInfo = new BeatmapTypeInfo(), + modDisplay = new ModDisplay + { + Scale = new Vector2(0.75f), + DisplayUnrankedText = false + }, + } + }, new Container { Anchor = Anchor.TopRight, @@ -70,13 +101,13 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.Y, Width = 200, Padding = new MarginPadding { Vertical = 5 }, - Child = beatmapButton = new BeatmapSelectButton + Child = beatmapButton = new BeatmapSelectButton(room) { RelativeSizeAxes = Axes.Both, Height = 1 }, }, - Tabs = new MatchTabControl + Tabs = new MatchTabControl(room) { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, @@ -86,6 +117,10 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; + beatmapTypeInfo.Beatmap.BindTo(Beatmap); + beatmapTypeInfo.Type.BindTo(Type); + modDisplay.Current.BindTo(Mods); + beatmapButton.Action = () => OnRequestSelectBeatmap?.Invoke(); background.Beatmap.BindTo(Beatmap); @@ -101,17 +136,10 @@ namespace osu.Game.Screens.Multi.Match.Components { private readonly IBindable roomIDBind = new Bindable(); - [Resolved] - private Room room { get; set; } - - public BeatmapSelectButton() + public BeatmapSelectButton(Room room) { Text = "Select beatmap"; - } - [BackgroundDependencyLoader] - private void load() - { roomIDBind.BindTo(room.RoomID); roomIDBind.BindValueChanged(v => this.FadeTo(v.HasValue ? 0 : 1), true); } diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index f63135fc2d..e972a9b6a4 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions; @@ -14,9 +13,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; -using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Components; -using osu.Game.Screens.Play.HUD; using osuTK; namespace osu.Game.Screens.Multi.Match.Components @@ -33,8 +30,6 @@ namespace osu.Game.Screens.Multi.Match.Components public readonly Bindable Availability = new Bindable(); public readonly Bindable Status = new Bindable(); public readonly Bindable Beatmap = new Bindable(); - public readonly Bindable Type = new Bindable(); - public readonly Bindable> Mods = new Bindable>(); public readonly Bindable EndDate = new Bindable(); public Info(Room room) @@ -44,9 +39,7 @@ namespace osu.Game.Screens.Multi.Match.Components ReadyButton readyButton; ViewBeatmapButton viewBeatmapButton; - BeatmapTypeInfo beatmapTypeInfo; OsuSpriteText name; - ModDisplay modDisplay; EndDateInfo endDate; Children = new Drawable[] @@ -82,20 +75,6 @@ namespace osu.Game.Screens.Multi.Match.Components endDate = new EndDateInfo { TextSize = 14 } } }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - beatmapTypeInfo = new BeatmapTypeInfo(), - modDisplay = new ModDisplay - { - Scale = new Vector2(0.75f), - DisplayUnrankedText = false - }, - } - } }, }, new FillFlowContainer @@ -119,10 +98,6 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - beatmapTypeInfo.Beatmap.BindTo(Beatmap); - beatmapTypeInfo.Type.BindTo(Type); - modDisplay.Current.BindTo(Mods); - viewBeatmapButton.Beatmap.BindTo(Beatmap); readyButton.Beatmap.BindTo(Beatmap); diff --git a/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs b/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs index 538dcc341e..a9932ee3c6 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs @@ -16,11 +16,10 @@ namespace osu.Game.Screens.Multi.Match.Components { private readonly IBindable roomIdBind = new Bindable(); - [Resolved] - private Room room { get; set; } - - public MatchTabControl() + public MatchTabControl(Room room) { + roomIdBind.BindTo(room.RoomID); + AddItem(new RoomMatchPage()); AddItem(new SettingsMatchPage()); } @@ -28,7 +27,6 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load() { - roomIdBind.BindTo(room.RoomID); roomIdBind.BindValueChanged(v => { if (v.HasValue) diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index d3098efb82..bab44d62b2 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -5,6 +5,7 @@ using System; using Humanizer; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -133,6 +134,7 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.X, Items = new[] { + TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(30), TimeSpan.FromHours(1), TimeSpan.FromHours(2), @@ -159,14 +161,29 @@ namespace osu.Game.Screens.Multi.Match.Components }, }, }, - ApplyButton = new CreateRoomButton + new Container { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Size = new Vector2(230, 35), - Margin = new MarginPadding { Bottom = 20 }, - Action = apply, - }, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Y = 2, + RelativeSizeAxes = Axes.X, + Height = 60, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"28242d").Darken(0.5f).Opacity(1f), + }, + ApplyButton = new CreateRoomButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(230, 35), + Action = apply, + }, + } + } }, }; diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index c169a5fb5d..656402d0f3 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Multi.Match RelativeSizeAxes = Axes.Both, Content = new[] { - new Drawable[] { header = new Components.Header { Depth = -1 } }, + new Drawable[] { header = new Components.Header(room) { Depth = -1 } }, new Drawable[] { info = new Info(room) { OnStart = onStart } }, new Drawable[] { @@ -135,9 +135,10 @@ namespace osu.Game.Screens.Multi.Match info.Name.BindTo(nameBind); info.Status.BindTo(statusBind); info.Availability.BindTo(availabilityBind); - info.Type.BindTo(typeBind); info.EndDate.BindTo(endDateBind); + header.Type.BindTo(typeBind); + participants.Users.BindTo(participantsBind); participants.MaxParticipants.BindTo(maxParticipantsBind); @@ -167,8 +168,8 @@ namespace osu.Game.Screens.Multi.Match var item = playlistBind.First(); header.Beatmap.Value = item.Beatmap; + header.Mods.Value = item.RequiredMods; info.Beatmap.Value = item.Beatmap; - info.Mods.Value = item.RequiredMods; // Todo: item.Beatmap can be null here... var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.BeatmapID) ?? item.Beatmap; From 1701af61d64ad2d16f51ad67e38ad402b0c49c7b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 17:33:55 +0900 Subject: [PATCH 089/220] Add host avatar+username to match screen --- .../Visual/TestCaseMatchHostInfo.cs | 29 ++++++++++ .../Screens/Multi/Match/Components/Header.cs | 7 +-- .../Multi/Match/Components/HostInfo.cs | 54 +++++++++++++++++++ .../Screens/Multi/Match/Components/Info.cs | 1 + 4 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs create mode 100644 osu.Game/Screens/Multi/Match/Components/HostInfo.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs new file mode 100644 index 0000000000..006af2e10e --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseMatchHostInfo : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(HostInfo) + }; + + public TestCaseMatchHostInfo() + { + Child = new HostInfo(new Room { Host = { Value = new User { Username = "ImAHost" }}}) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }; + } + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index de93e8587f..3f4f137413 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -73,16 +73,13 @@ namespace osu.Game.Screens.Multi.Match.Components new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding - { - Left = SearchableListOverlay.WIDTH_PADDING, - Top = 20 - }, + Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, Children = new Drawable[] { new FillFlowContainer { AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 20 }, Direction = FillDirection.Vertical, Children = new Drawable[] { diff --git a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs new file mode 100644 index 0000000000..e77f534a17 --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Containers; +using osu.Game.Online.Chat; +using osu.Game.Online.Multiplayer; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class HostInfo : CompositeDrawable + { + public HostInfo(Room room) + { + AutoSizeAxes = Axes.X; + Height = 50; + + LinkFlowContainer linkContainer; + + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new UpdateableAvatar + { + Size = new Vector2(50), + User = room.Host.Value + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + linkContainer = new LinkFlowContainer { AutoSizeAxes = Axes.Both } + } + } + } + }; + + linkContainer.AddText("hosted by"); + linkContainer.NewLine(); + linkContainer.AddLink(room.Host.Value.Username,null, LinkAction.OpenUserProfile, room.Host.Value.Id.ToString(), "Open profile", s => s.Font = "Exo2.0-BoldItalic"); + } + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index e972a9b6a4..de02899a01 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -75,6 +75,7 @@ namespace osu.Game.Screens.Multi.Match.Components endDate = new EndDateInfo { TextSize = 14 } } }, + new HostInfo(room), }, }, new FillFlowContainer From 8db3ac0a9f209102f3af081a5c025f773fc72e81 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 18:04:35 +0900 Subject: [PATCH 090/220] Make user links clickable --- .../Lounge/Components/ParticipantInfo.cs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs index 3bc20b58c5..042dd96b61 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs @@ -9,7 +9,9 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Online.Chat; using osu.Game.Users; using osuTK; @@ -17,7 +19,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components { public class ParticipantInfo : Container { - private readonly OsuSpriteText host; private readonly FillFlowContainer levelRangeContainer; public readonly Bindable Host = new Bindable(); @@ -31,6 +32,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components OsuSpriteText levelRangeHigher; OsuSpriteText levelRangeLower; Container flagContainer; + LinkFlowContainer hostText; Children = new Drawable[] { @@ -62,20 +64,12 @@ namespace osu.Game.Screens.Multi.Lounge.Components }, }, }, - new OsuSpriteText - { - Text = "hosted by", - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = 14, - }, - host = new OsuSpriteText + hostText = new LinkFlowContainer { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - TextSize = 14, - Font = @"Exo2.0-BoldItalic", - }, + AutoSizeAxes = Axes.Both + } }, }, levelRangeContainer = new FillFlowContainer @@ -122,7 +116,10 @@ namespace osu.Game.Screens.Multi.Lounge.Components Host.BindValueChanged(v => { - host.Text = v.Username; + hostText.Clear(); + hostText.AddText("hosted by "); + hostText.AddLink(v.Username, null, LinkAction.OpenUserProfile, v.Id.ToString(), "Open profile", s => s.Font = "Exo2.0-BoldItalic"); + flagContainer.Child = new DrawableFlag(v.Country) { RelativeSizeAxes = Axes.Both }; }); @@ -138,7 +135,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components private void load(OsuColour colours) { levelRangeContainer.Colour = colours.Gray9; - host.Colour = colours.Blue; } } } From deaf4ab4a12e5f656e090b5080d35536711532f5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 18:21:55 +0900 Subject: [PATCH 091/220] Cleanup --- osu.Game/Screens/Multi/Match/Components/HostInfo.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs index e77f534a17..830d720bd4 100644 --- a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs +++ b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs @@ -38,10 +38,7 @@ namespace osu.Game.Screens.Multi.Match.Components Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, - Children = new Drawable[] - { - linkContainer = new LinkFlowContainer { AutoSizeAxes = Axes.Both } - } + Child = linkContainer = new LinkFlowContainer { AutoSizeAxes = Axes.Both } } } }; From f8d25a1b6ca15d598284a5323e5ff4867db40ae2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 20:01:58 +0900 Subject: [PATCH 092/220] Add method to add arbitrary drawables as links --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 795fe7caf4..ce1e583c6f 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; using System.Collections.Generic; +using osu.Framework.Graphics; using osu.Framework.Logging; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; @@ -61,8 +62,19 @@ namespace osu.Game.Graphics.Containers } public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action creationParameters = null) + => createLink(AddText(text, creationParameters), text, url, linkType, linkArgument, tooltipText); + + public void AddLink(IEnumerable text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null) { - AddInternal(new DrawableLinkCompiler(AddText(text, creationParameters).OfType().ToList()) + foreach (var t in text) + AddArbitraryDrawable(t); + + createLink(text, null, url, linkType, linkArgument, tooltipText); + } + + private void createLink(IEnumerable drawables, string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null) + { + AddInternal(new DrawableLinkCompiler(drawables.OfType().ToList()) { TooltipText = tooltipText ?? (url != text ? url : string.Empty), Action = () => From 6a76e335c726b5d4753d4fb250dc0b6e22073167 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 20:03:39 +0900 Subject: [PATCH 093/220] Linkify everything --- .../Screens/Multi/Components/BeatmapTitle.cs | 56 ++++++++++++------- .../Multi/Components/BeatmapTypeInfo.cs | 26 +++++---- .../Multi/Lounge/Components/DrawableRoom.cs | 1 - .../Multi/Match/Components/HostInfo.cs | 2 +- 4 files changed, 51 insertions(+), 34 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index 02ec598f82..67d414a080 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs @@ -6,36 +6,38 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; using osu.Game.Beatmaps; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Online.Chat; namespace osu.Game.Screens.Multi.Components { public class BeatmapTitle : CompositeDrawable { - private readonly OsuSpriteText beatmapTitle, beatmapDash, beatmapArtist; + private float textSize = OsuSpriteText.FONT_SIZE; public float TextSize { - set { beatmapTitle.TextSize = beatmapDash.TextSize = beatmapArtist.TextSize = value; } + get => textSize; + set + { + if (textSize == value) + return; + textSize = value; + + updateText(); + } } public readonly IBindable Beatmap = new Bindable(); + private readonly LinkFlowContainer textFlow; + public BeatmapTitle() { AutoSizeAxes = Axes.Both; - InternalChild = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new[] - { - beatmapTitle = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", }, - beatmapDash = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", }, - beatmapArtist = new OsuSpriteText { Font = @"Exo2.0-RegularItalic", }, - } - }; + InternalChild = textFlow = new LinkFlowContainer { AutoSizeAxes = Axes.Both }; Beatmap.BindValueChanged(v => updateText()); } @@ -51,16 +53,30 @@ namespace osu.Game.Screens.Multi.Components if (!IsLoaded) return; + textFlow.Clear(); + if (Beatmap.Value == null) - { - beatmapTitle.Text = "Changing map"; - beatmapDash.Text = beatmapArtist.Text = string.Empty; - } + textFlow.AddText("Changing map", s => s.TextSize = TextSize); else { - beatmapTitle.Text = new LocalisedString((Beatmap.Value.Metadata.TitleUnicode, Beatmap.Value.Metadata.Title)); - beatmapDash.Text = @" - "; - beatmapArtist.Text = new LocalisedString((Beatmap.Value.Metadata.ArtistUnicode, Beatmap.Value.Metadata.Artist)); + textFlow.AddLink(new[] + { + new OsuSpriteText + { + Text = new LocalisedString((Beatmap.Value.Metadata.ArtistUnicode, Beatmap.Value.Metadata.Artist)), + TextSize = TextSize, + }, + new OsuSpriteText + { + Text = " - ", + TextSize = TextSize, + }, + new OsuSpriteText + { + Text = new LocalisedString((Beatmap.Value.Metadata.TitleUnicode, Beatmap.Value.Metadata.Title)), + TextSize = TextSize, + } + }, null, LinkAction.OpenBeatmap, Beatmap.Value.OnlineBeatmapID.ToString(), "Open beatmap"); } } } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs index 90319de40f..a06eaa35dc 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs @@ -1,13 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.Containers; +using osu.Game.Online.Chat; using osu.Game.Online.Multiplayer; using osuTK; @@ -15,8 +15,6 @@ namespace osu.Game.Screens.Multi.Components { public class BeatmapTypeInfo : CompositeDrawable { - private readonly OsuSpriteText beatmapAuthor; - public readonly IBindable Beatmap = new Bindable(); public readonly IBindable Type = new Bindable(); @@ -27,6 +25,7 @@ namespace osu.Game.Screens.Multi.Components BeatmapTitle beatmapTitle; ModeTypeInfo modeTypeInfo; + LinkFlowContainer beatmapAuthor; InternalChild = new FillFlowContainer { @@ -45,11 +44,11 @@ namespace osu.Game.Screens.Multi.Components Children = new Drawable[] { beatmapTitle = new BeatmapTitle(), - beatmapAuthor = new OsuSpriteText + beatmapAuthor = new LinkFlowContainer(s => s.TextSize = 14) { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - TextSize = 14, + AutoSizeAxes = Axes.Both }, }, }, @@ -61,13 +60,16 @@ namespace osu.Game.Screens.Multi.Components beatmapTitle.Beatmap.BindTo(Beatmap); - Beatmap.BindValueChanged(v => beatmapAuthor.Text = v == null ? string.Empty : $"mapped by {v.Metadata.Author}"); - } + Beatmap.BindValueChanged(v => + { + beatmapAuthor.Clear(); - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - beatmapAuthor.Colour = colours.GrayC; + if (v != null) + { + beatmapAuthor.AddText("mapped by ", s => s.Colour = OsuColour.Gray(0.8f)); + beatmapAuthor.AddLink(v.Metadata.Author.Username, null, LinkAction.OpenUserProfile, v.Metadata.Author.Id.ToString(), "View Profile"); + } + }); } } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index c1a9dd3b1d..f4e304d0a8 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -205,7 +205,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components beatmapTitle = new BeatmapTitle { TextSize = 14, - Colour = colours.Gray9 }, } } diff --git a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs index 830d720bd4..883f88b056 100644 --- a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs +++ b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Multi.Match.Components linkContainer.AddText("hosted by"); linkContainer.NewLine(); - linkContainer.AddLink(room.Host.Value.Username,null, LinkAction.OpenUserProfile, room.Host.Value.Id.ToString(), "Open profile", s => s.Font = "Exo2.0-BoldItalic"); + linkContainer.AddLink(room.Host.Value.Username, null, LinkAction.OpenUserProfile, room.Host.Value.Id.ToString(), "View Profile", s => s.Font = "Exo2.0-BoldItalic"); } } } From 104a3c8ffcd5ababd52b66e1d0db183b6fa9c417 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 20:08:22 +0900 Subject: [PATCH 094/220] Add click to avatar --- osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 12 +---- osu.Game/Overlays/Profile/ProfileHeader.cs | 1 + .../Overlays/Toolbar/ToolbarUserButton.cs | 1 + osu.Game/Users/Avatar.cs | 51 +++++++++++++++++-- osu.Game/Users/UpdateableAvatar.cs | 23 ++++++--- osu.Game/Users/UserPanel.cs | 1 + 6 files changed, 67 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index c2f03a4b66..0b260d4f39 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -9,7 +9,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Users; using osuTK; using osuTK.Graphics; -using osu.Framework.Allocation; using osu.Game.Graphics.Containers; using osu.Framework.Graphics.Cursor; @@ -20,7 +19,6 @@ namespace osu.Game.Overlays.BeatmapSet private const float height = 50; private readonly UpdateableAvatar avatar; - private readonly ClickableArea clickableArea; private readonly FillFlowContainer fields; private BeatmapSetInfo beatmapSet; @@ -73,7 +71,7 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { - clickableArea = new ClickableArea + new Container { AutoSizeAxes = Axes.Both, CornerRadius = 3, @@ -100,14 +98,8 @@ namespace osu.Game.Overlays.BeatmapSet }; } - [BackgroundDependencyLoader(true)] - private void load(UserProfileOverlay profile) + private void load() { - clickableArea.Action = () => - { - if (avatar.User != null) profile?.ShowUser(avatar.User); - }; - updateDisplay(); } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index a8075ec295..3c7fe0b1eb 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -82,6 +82,7 @@ namespace osu.Game.Overlays.Profile Origin = Anchor.BottomLeft, Masking = true, CornerRadius = 5, + OpenOnClick = { Value = false }, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, diff --git a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs index 017d748600..36299e51f0 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs @@ -31,6 +31,7 @@ namespace osu.Game.Overlays.Toolbar Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, CornerRadius = 4, + OpenOnClick = { Value = false }, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, diff --git a/osu.Game/Users/Avatar.cs b/osu.Game/Users/Avatar.cs index e6e1ba3c53..24864cce51 100644 --- a/osu.Game/Users/Avatar.cs +++ b/osu.Game/Users/Avatar.cs @@ -3,17 +3,29 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; namespace osu.Game.Users { public class Avatar : Container { + /// + /// Whether to open the user's profile when clicked. + /// + public readonly BindableBool OpenOnClick = new BindableBool(true); + private readonly User user; + [Resolved(CanBeNull = true)] + private OsuGame game { get; set; } + /// /// An avatar for specified user. /// @@ -33,14 +45,43 @@ namespace osu.Game.Users if (user != null && user.Id > 1) texture = textures.Get($@"https://a.ppy.sh/{user.Id}"); if (texture == null) texture = textures.Get(@"Online/avatar-guest"); - Add(new Sprite + ClickableArea clickableArea; + Add(clickableArea = new ClickableArea { RelativeSizeAxes = Axes.Both, - Texture = texture, - FillMode = FillMode.Fit, - Anchor = Anchor.Centre, - Origin = Anchor.Centre + Child = new Sprite + { + RelativeSizeAxes = Axes.Both, + Texture = texture, + FillMode = FillMode.Fit, + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }, + Action = openProfile }); + + clickableArea.Enabled.BindTo(OpenOnClick); + } + + private void openProfile() + { + if (!OpenOnClick) + return; + + if (user != null) + game?.ShowUser(user.Id); + } + + private class ClickableArea : OsuClickableContainer, IHasTooltip + { + public string TooltipText => Enabled.Value ? @"View Profile" : null; + + protected override bool OnClick(ClickEvent e) + { + if (!Enabled) + return false; + return base.OnClick(e); + } } } } diff --git a/osu.Game/Users/UpdateableAvatar.cs b/osu.Game/Users/UpdateableAvatar.cs index 6c0b841abf..a8d9d3d66b 100644 --- a/osu.Game/Users/UpdateableAvatar.cs +++ b/osu.Game/Users/UpdateableAvatar.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -35,6 +36,11 @@ namespace osu.Game.Users } } + /// + /// Whether to open the user's profile when clicked. + /// + public readonly BindableBool OpenOnClick = new BindableBool(true); + protected override void LoadComplete() { base.LoadComplete(); @@ -45,15 +51,18 @@ namespace osu.Game.Users { displayedAvatar?.FadeOut(300); displayedAvatar?.Expire(); + if (user != null || ShowGuestOnNull) { - Add(displayedAvatar = new DelayedLoadWrapper( - new Avatar(user) - { - RelativeSizeAxes = Axes.Both, - OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint), - }) - ); + var avatar = new Avatar(user) + { + RelativeSizeAxes = Axes.Both, + OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint), + }; + + avatar.OpenOnClick.BindTo(OpenOnClick); + + Add(displayedAvatar = new DelayedLoadWrapper(avatar)); } } } diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index d86f608bd1..1d302ef04f 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -99,6 +99,7 @@ namespace osu.Game.Users User = user, Masking = true, CornerRadius = 5, + OpenOnClick = { Value = false }, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, From 9031896484d01de2ec4b517f83b53b6539c3d0b1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 20:09:17 +0900 Subject: [PATCH 095/220] Fix create room button showing in song select --- osu.Game/Screens/Multi/Multiplayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 4a0fa141c8..0239042241 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -149,7 +149,7 @@ namespace osu.Game.Screens.Multi createButton.Hide(); } - else + else if (currentScreen is LoungeScreen) createButton.Show(); } From 822225577b8f072501fde2959691f94d98ead5b7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Dec 2018 20:58:34 +0900 Subject: [PATCH 096/220] Add joining/parting room requests --- .../Multi/Lounge/Components/RoomInspector.cs | 2 +- .../Multi/Lounge/Components/RoomsContainer.cs | 19 ++--- osu.Game/Screens/Multi/Lounge/LoungeScreen.cs | 12 +-- osu.Game/Screens/Multi/Match/MatchScreen.cs | 7 +- osu.Game/Screens/Multi/Multiplayer.cs | 5 +- osu.Game/Screens/Multi/RoomManager.cs | 78 ++++++++++++++++++- 6 files changed, 99 insertions(+), 24 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 80adc8787f..f290830334 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components { private const float transition_duration = 100; - public readonly Bindable Room = new Bindable(); + public readonly IBindable Room = new Bindable(); private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; private readonly Bindable nameBind = new Bindable(); diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index bde76a01df..b17ddca21d 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -17,10 +17,12 @@ namespace osu.Game.Screens.Multi.Lounge.Components { public class RoomsContainer : CompositeDrawable, IHasFilterableChildren { - public Action OpenRequested; + public Action JoinRequested; + + private readonly Bindable selectedRoom = new Bindable(); + public IBindable SelectedRoom => selectedRoom; private readonly IBindableCollection rooms = new BindableCollection(); - private readonly Bindable currentRoom = new Bindable(); private readonly FillFlowContainer roomFlow; @@ -44,15 +46,12 @@ namespace osu.Game.Screens.Multi.Lounge.Components [BackgroundDependencyLoader] private void load() { - currentRoom.BindTo(manager.Current); rooms.BindTo(manager.Rooms); rooms.ItemsAdded += addRooms; rooms.ItemsRemoved += removeRooms; addRooms(rooms); - - currentRoom.BindValueChanged(selectRoom, true); } private FilterCriteria currentFilter; @@ -100,8 +99,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components roomFlow.Remove(toRemove); - if (currentRoom.Value == r) - currentRoom.Value = null; + selectRoom(null); } } @@ -110,12 +108,11 @@ namespace osu.Game.Screens.Multi.Lounge.Components var drawable = roomFlow.FirstOrDefault(r => r.Room == room); if (drawable != null && drawable.State == SelectionState.Selected) - OpenRequested?.Invoke(room); + JoinRequested?.Invoke(room); else - { - currentRoom.Value = room; roomFlow.Children.ForEach(r => r.State = r.Room == room ? SelectionState.Selected : SelectionState.NotSelected); - } + + selectedRoom.Value = room; } public IEnumerable FilterTerms => Enumerable.Empty(); diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index 408c02f805..562dfaa347 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Multi.Lounge { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = rooms = new RoomsContainer { OpenRequested = Open } + Child = rooms = new RoomsContainer { JoinRequested = r => manager?.JoinRoom(r) } }, }, inspector = new RoomInspector @@ -68,10 +68,10 @@ namespace osu.Game.Screens.Multi.Lounge }, }, }, - manager = new RoomManager() + manager = new RoomManager { OpenRequested = Open } }; - inspector.Room.BindTo(manager.Current); + inspector.Room.BindTo(rooms.SelectedRoom); Filter.Search.Current.ValueChanged += s => filterRooms(); Filter.Tabs.Current.ValueChanged += t => filterRooms(); @@ -103,15 +103,17 @@ namespace osu.Game.Screens.Multi.Lounge protected override bool OnExiting(Screen next) { + manager?.PartRoom(); + Filter.Search.HoldFocus = false; return base.OnExiting(next); } protected override void OnResuming(Screen last) { - base.OnResuming(last); + manager?.PartRoom(); - Filter.Search.HoldFocus = true; + base.OnResuming(last); } protected override void OnSuspending(Screen next) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 656402d0f3..b33c871fad 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; -using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Play; @@ -52,12 +51,12 @@ namespace osu.Game.Screens.Multi.Match [Resolved] private BeatmapManager beatmapManager { get; set; } - [Resolved] - private APIAccess api { get; set; } - [Resolved] private OsuGame game { get; set; } + [Resolved(CanBeNull = true)] + private RoomManager manager { get; set; } + public MatchScreen(Room room, Action pushGameplayScreen) { this.room = room; diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 0239042241..9339c6693f 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -27,6 +27,7 @@ namespace osu.Game.Screens.Multi public override bool AllowBeatmapRulesetChange => currentScreen?.AllowBeatmapRulesetChange ?? base.AllowBeatmapRulesetChange; private readonly OsuButton createButton; + private readonly LoungeScreen loungeScreen; private OsuScreen currentScreen; @@ -37,7 +38,6 @@ namespace osu.Game.Screens.Multi RelativeSizeAxes = Axes.Both, }; - LoungeScreen loungeScreen; waves.AddRange(new Drawable[] { new Container @@ -102,6 +102,9 @@ namespace osu.Game.Screens.Multi if (track != null) track.Looping = false; + loungeScreen.MakeCurrent(); + loungeScreen.Exit(); + return base.OnExiting(next); } diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 8e887e51e1..b3bb9cb147 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; @@ -16,15 +17,18 @@ using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; using osu.Game.Screens.Multi.Lounge.Components; +using osu.Game.Users; namespace osu.Game.Screens.Multi { public class RoomManager : PollingComponent { + public Action OpenRequested; + public IBindableCollection Rooms => rooms; private readonly BindableCollection rooms = new BindableCollection(); - public readonly Bindable Current = new Bindable(); + private Room currentRoom; private FilterCriteria currentFilter = new FilterCriteria(); @@ -47,12 +51,40 @@ namespace osu.Game.Screens.Multi room.Host.Value = api.LocalUser; var req = new CreateRoomRequest(room); - req.Success += result => addRoom(room, result); req.Failure += exception => Logger.Log($"Failed to create room: {exception}"); + api.Queue(req); } + private JoinRoomRequest currentJoinRoomRequest; + + public void JoinRoom(Room room) + { + currentJoinRoomRequest?.Cancel(); + currentJoinRoomRequest = null; + + currentJoinRoomRequest = new JoinRoomRequest(room, api.LocalUser.Value); + currentJoinRoomRequest.Success += () => + { + currentRoom = room; + OpenRequested?.Invoke(room); + }; + + currentJoinRoomRequest.Failure += exception => Logger.Log($"Failed to join room: {exception}"); + + api.Queue(currentJoinRoomRequest); + } + + public void PartRoom() + { + if (currentRoom == null) + return; + + api.Queue(new PartRoomRequest(currentRoom, api.LocalUser.Value)); + currentRoom = null; + } + public void Filter(FilterCriteria criteria) { currentFilter = criteria; @@ -141,6 +173,48 @@ namespace osu.Game.Screens.Multi protected override string Target => "rooms"; } + private class JoinRoomRequest : APIRequest + { + private readonly Room room; + private readonly User user; + + public JoinRoomRequest(Room room, User user) + { + this.room = room; + this.user = user; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Put; + return req; + } + + protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}"; + } + + private class PartRoomRequest : APIRequest + { + private readonly Room room; + private readonly User user; + + public PartRoomRequest(Room room, User user) + { + this.room = room; + this.user = user; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Delete; + return req; + } + + protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}"; + } + private class GetRoomsRequest : APIRequest> { private readonly PrimaryFilter primaryFilter; From e27b7b0c0d1f594e8fd9d7933356c7cc9eb152aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 13:06:11 +0900 Subject: [PATCH 097/220] Cleanup --- osu.Game/Online/Multiplayer/Room.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 39319aa32e..80a4be83eb 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -22,28 +22,28 @@ namespace osu.Game.Online.Multiplayer public Bindable Host { get; private set; } = new Bindable(); [JsonProperty("playlist")] - public readonly BindableCollection Playlist = new BindableCollection(); + public BindableCollection Playlist { get; set; } = new BindableCollection(); [JsonIgnore] - public readonly Bindable Duration = new Bindable(TimeSpan.FromMinutes(30)); + public Bindable Duration { get; private set; } = new Bindable(TimeSpan.FromMinutes(30)); [JsonIgnore] - public readonly Bindable MaxAttempts = new Bindable(); + public Bindable MaxAttempts { get; private set; } = new Bindable(); [JsonIgnore] - public Bindable Status = new Bindable(new RoomStatusOpen()); + public Bindable Status { get; private set; } = new Bindable(new RoomStatusOpen()); [JsonIgnore] - public Bindable Availability = new Bindable(); + public Bindable Availability { get; private set; } = new Bindable(); [JsonIgnore] - public Bindable Type = new Bindable(new GameTypeTimeshift()); + public Bindable Type { get; private set; } = new Bindable(new GameTypeTimeshift()); [JsonIgnore] - public Bindable MaxParticipants = new Bindable(); + public Bindable MaxParticipants { get; private set; } = new Bindable(); [JsonIgnore] - public Bindable> Participants = new Bindable>(Enumerable.Empty()); + public Bindable> Participants { get; private set; } = new Bindable>(Enumerable.Empty()); [JsonProperty("duration")] private int duration @@ -54,7 +54,7 @@ namespace osu.Game.Online.Multiplayer // Only supports retrieval for now [JsonProperty("ends_at")] - public Bindable EndDate = new Bindable(); + public Bindable EndDate { get; private set; } = new Bindable(); // Todo: Find a better way to do this (https://github.com/ppy/osu-framework/issues/1930) [JsonProperty("max_attempts", DefaultValueHandling = DefaultValueHandling.Ignore)] From 14879acd83c28391fc0f2b588a2f00fe47afbe3f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 13:26:50 +0900 Subject: [PATCH 098/220] Fix possible nullref --- osu.Game/Screens/Multi/Match/Components/HostInfo.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs index 883f88b056..01b84bd40b 100644 --- a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs +++ b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs @@ -43,9 +43,12 @@ namespace osu.Game.Screens.Multi.Match.Components } }; - linkContainer.AddText("hosted by"); - linkContainer.NewLine(); - linkContainer.AddLink(room.Host.Value.Username, null, LinkAction.OpenUserProfile, room.Host.Value.Id.ToString(), "View Profile", s => s.Font = "Exo2.0-BoldItalic"); + if (room.Host.Value != null) + { + linkContainer.AddText("hosted by"); + linkContainer.NewLine(); + linkContainer.AddLink(room.Host.Value.Username, null, LinkAction.OpenUserProfile, room.Host.Value.Id.ToString(), "View Profile", s => s.Font = "Exo2.0-BoldItalic"); + } } } } From fa2bc16140cf0e27caa6d2eee5f7173567cf6f0b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 14:01:06 +0900 Subject: [PATCH 099/220] Remove participants, add match chat --- osu.Game/Online/Multiplayer/Room.cs | 3 ++ .../Match/Components/MatchChatDisplay.cs | 30 +++++++++++++++++++ osu.Game/Screens/Multi/Match/MatchScreen.cs | 16 ++-------- 3 files changed, 35 insertions(+), 14 deletions(-) create mode 100644 osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 80a4be83eb..16b0c588fa 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -24,6 +24,9 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("playlist")] public BindableCollection Playlist { get; set; } = new BindableCollection(); + [JsonProperty("channel_id")] + public Bindable ChannelId { get; private set; } = new Bindable(); + [JsonIgnore] public Bindable Duration { get; private set; } = new Bindable(TimeSpan.FromMinutes(30)); diff --git a/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs b/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs new file mode 100644 index 0000000000..9c02439f7c --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Online.Chat; +using osu.Game.Online.Multiplayer; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class MatchChatDisplay : StandAloneChatDisplay + { + private readonly Room room; + + [Resolved] + private ChannelManager channelManager { get; set; } + + public MatchChatDisplay(Room room) + : base(true) + { + this.room = room; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Channel.Value = channelManager.JoinChannel(new Channel { Id = room.ChannelId, Type = ChannelType.Multiplayer, Name = $"#mp_{room.RoomID}" }); + } + } +} diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index b33c871fad..b865c07e31 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -21,8 +21,6 @@ namespace osu.Game.Screens.Multi.Match { public class MatchScreen : MultiplayerScreen { - private readonly Participants participants; - private readonly Bindable nameBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); private readonly Bindable availabilityBind = new Bindable(); @@ -34,8 +32,6 @@ namespace osu.Game.Screens.Multi.Match public override bool AllowBeatmapRulesetChange => false; - protected override Drawable TransitionContent => participants; - public override string Title => room.Name.Value; public override string ShortTitle => "room"; @@ -90,15 +86,10 @@ namespace osu.Game.Screens.Multi.Match { new Drawable[] { - participants = new Participants { RelativeSizeAxes = Axes.Both }, - leaderboard = new MatchLeaderboard(room) { RelativeSizeAxes = Axes.Both } + leaderboard = new MatchLeaderboard(room) { RelativeSizeAxes = Axes.Both }, + new MatchChatDisplay(room) { RelativeSizeAxes = Axes.Both } }, }, - ColumnDimensions = new[] - { - new Dimension(GridSizeMode.Distributed), - new Dimension(GridSizeMode.Relative, 0.5f), - } } }, }, @@ -138,9 +129,6 @@ namespace osu.Game.Screens.Multi.Match header.Type.BindTo(typeBind); - participants.Users.BindTo(participantsBind); - participants.MaxParticipants.BindTo(maxParticipantsBind); - playlistBind.ItemsAdded += _ => setFromPlaylist(); playlistBind.ItemsRemoved += _ => setFromPlaylist(); } From fe6c369e0765ce8fd8d16229d40e3944c76b6ea4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 14:37:05 +0900 Subject: [PATCH 100/220] Fix incorrect channel --- .../Screens/Multi/Match/Components/MatchChatDisplay.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs b/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs index 9c02439f7c..ecb7b86fb4 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs @@ -24,7 +24,13 @@ namespace osu.Game.Screens.Multi.Match.Components { base.LoadComplete(); - Channel.Value = channelManager.JoinChannel(new Channel { Id = room.ChannelId, Type = ChannelType.Multiplayer, Name = $"#mp_{room.RoomID}" }); + room.RoomID.BindValueChanged(v => updateChannel(), true); + } + + private void updateChannel() + { + if (room.RoomID.Value != null) + Channel.Value = channelManager.JoinChannel(new Channel { Id = room.ChannelId, Type = ChannelType.Multiplayer, Name = $"#mp_{room.RoomID}" }); } } } From 8a2cc64bfa0145769435e09de24bd1c6557223b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 16:28:33 +0900 Subject: [PATCH 101/220] Split results screen to allow for extensibility --- osu.Game.Tests/Visual/TestCaseResults.cs | 8 ++-- osu.Game/Screens/Play/Player.cs | 3 +- osu.Game/Screens/Play/SoloResults.cs | 24 +++++++++++ .../RankingResultsPage.cs} | 11 ++--- .../Ranking/{ => Pages}/ResultsPage.cs | 2 +- .../ScoreResultsPage.cs} | 23 +++++----- osu.Game/Screens/Ranking/ResultMode.cs | 12 ------ osu.Game/Screens/Ranking/ResultModeButton.cs | 19 +++----- .../Screens/Ranking/ResultModeTabControl.cs | 7 +-- osu.Game/Screens/Ranking/Results.cs | 43 ++++++++----------- osu.Game/Screens/Ranking/Types/IResultType.cs | 15 +++++++ .../Ranking/Types/RankingResultType.cs | 26 +++++++++++ .../Screens/Ranking/Types/ScoreResultType.cs | 26 +++++++++++ osu.Game/Screens/Select/SongSelect.cs | 4 +- 14 files changed, 147 insertions(+), 76 deletions(-) create mode 100644 osu.Game/Screens/Play/SoloResults.cs rename osu.Game/Screens/Ranking/{ResultsPageRanking.cs => Pages/RankingResultsPage.cs} (83%) rename osu.Game/Screens/Ranking/{ => Pages}/ResultsPage.cs (98%) rename osu.Game/Screens/Ranking/{ResultsPageScore.cs => Pages/ScoreResultsPage.cs} (98%) delete mode 100644 osu.Game/Screens/Ranking/ResultMode.cs create mode 100644 osu.Game/Screens/Ranking/Types/IResultType.cs create mode 100644 osu.Game/Screens/Ranking/Types/RankingResultType.cs create mode 100644 osu.Game/Screens/Ranking/Types/ScoreResultType.cs diff --git a/osu.Game.Tests/Visual/TestCaseResults.cs b/osu.Game.Tests/Visual/TestCaseResults.cs index 6a20a808b6..a954c6c57c 100644 --- a/osu.Game.Tests/Visual/TestCaseResults.cs +++ b/osu.Game.Tests/Visual/TestCaseResults.cs @@ -8,7 +8,9 @@ using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; +using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; +using osu.Game.Screens.Ranking.Pages; using osu.Game.Users; namespace osu.Game.Tests.Visual @@ -23,8 +25,8 @@ namespace osu.Game.Tests.Visual typeof(ScoreInfo), typeof(Results), typeof(ResultsPage), - typeof(ResultsPageScore), - typeof(ResultsPageRanking) + typeof(ScoreResultsPage), + typeof(RankingResultsPage) }; [BackgroundDependencyLoader] @@ -41,7 +43,7 @@ namespace osu.Game.Tests.Visual if (beatmapInfo != null) Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo); - Add(new Results(new ScoreInfo + Add(new SoloResults(new ScoreInfo { TotalScore = 2845370, Accuracy = 0.98, diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 19b49b099c..1429675ddd 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -28,7 +28,6 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; -using osu.Game.Screens.Ranking; using osu.Game.Skinning; using osu.Game.Storyboards.Drawables; @@ -288,7 +287,7 @@ namespace osu.Game.Screens.Play if (RulesetContainer.Replay == null) scoreManager.Import(score, true); - Push(new Results(score)); + Push(new SoloResults(score)); onCompletionEvent = null; }); diff --git a/osu.Game/Screens/Play/SoloResults.cs b/osu.Game/Screens/Play/SoloResults.cs new file mode 100644 index 0000000000..717efd118e --- /dev/null +++ b/osu.Game/Screens/Play/SoloResults.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Scoring; +using osu.Game.Screens.Ranking; +using osu.Game.Screens.Ranking.Types; + +namespace osu.Game.Screens.Play +{ + public class SoloResults : Results + { + public SoloResults(ScoreInfo score) + : base(score) + { + } + + protected override IEnumerable CreateResultTypes() => new IResultType[] + { + new ScoreResultType(Score, Beatmap), + new RankingResultType(Score, Beatmap) + }; + } +} diff --git a/osu.Game/Screens/Ranking/ResultsPageRanking.cs b/osu.Game/Screens/Ranking/Pages/RankingResultsPage.cs similarity index 83% rename from osu.Game/Screens/Ranking/ResultsPageRanking.cs rename to osu.Game/Screens/Ranking/Pages/RankingResultsPage.cs index 3a75daaf60..4c98e476c4 100644 --- a/osu.Game/Screens/Ranking/ResultsPageRanking.cs +++ b/osu.Game/Screens/Ranking/Pages/RankingResultsPage.cs @@ -3,18 +3,19 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Scoring; using osu.Game.Screens.Select.Leaderboards; using osuTK; -using osu.Framework.Graphics.Shapes; -using osu.Game.Scoring; -namespace osu.Game.Screens.Ranking +namespace osu.Game.Screens.Ranking.Pages { - public class ResultsPageRanking : ResultsPage + public class RankingResultsPage : ResultsPage { - public ResultsPageRanking(ScoreInfo score, WorkingBeatmap beatmap = null) : base(score, beatmap) + public RankingResultsPage(ScoreInfo score, WorkingBeatmap beatmap = null) + : base(score, beatmap) { } diff --git a/osu.Game/Screens/Ranking/ResultsPage.cs b/osu.Game/Screens/Ranking/Pages/ResultsPage.cs similarity index 98% rename from osu.Game/Screens/Ranking/ResultsPage.cs rename to osu.Game/Screens/Ranking/Pages/ResultsPage.cs index 5f68623e54..2e379d0a76 100644 --- a/osu.Game/Screens/Ranking/ResultsPage.cs +++ b/osu.Game/Screens/Ranking/Pages/ResultsPage.cs @@ -12,7 +12,7 @@ using osu.Game.Scoring; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Ranking +namespace osu.Game.Screens.Ranking.Pages { public class ResultsPage : Container { diff --git a/osu.Game/Screens/Ranking/ResultsPageScore.cs b/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs similarity index 98% rename from osu.Game/Screens/Ranking/ResultsPageScore.cs rename to osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs index 0774a63e98..8f5b21a7cb 100644 --- a/osu.Game/Screens/Ranking/ResultsPageScore.cs +++ b/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs @@ -4,36 +4,39 @@ using System; using System.Collections.Generic; using System.Linq; -using osuTK; -using osuTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Leaderboards; using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; using osu.Game.Screens.Play; using osu.Game.Users; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Extensions; -using osu.Framework.Localisation; -using osu.Game.Online.Leaderboards; -using osu.Game.Scoring; +using osuTK; +using osuTK.Graphics; -namespace osu.Game.Screens.Ranking +namespace osu.Game.Screens.Ranking.Pages { - public class ResultsPageScore : ResultsPage + public class ScoreResultsPage : ResultsPage { private Container scoreContainer; private ScoreCounter scoreCounter; - public ResultsPageScore(ScoreInfo score, WorkingBeatmap beatmap) : base(score, beatmap) { } + public ScoreResultsPage(ScoreInfo score, WorkingBeatmap beatmap) + : base(score, beatmap) + { + } private FillFlowContainer statisticsContainer; diff --git a/osu.Game/Screens/Ranking/ResultMode.cs b/osu.Game/Screens/Ranking/ResultMode.cs deleted file mode 100644 index 4742864b83..0000000000 --- a/osu.Game/Screens/Ranking/ResultMode.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Screens.Ranking -{ - public enum ResultMode - { - Summary, - Ranking, - Share - } -} diff --git a/osu.Game/Screens/Ranking/ResultModeButton.cs b/osu.Game/Screens/Ranking/ResultModeButton.cs index 5df3ff3afb..da0eb3dfcc 100644 --- a/osu.Game/Screens/Ranking/ResultModeButton.cs +++ b/osu.Game/Screens/Ranking/ResultModeButton.cs @@ -10,30 +10,21 @@ using osu.Game.Graphics; using osuTK; using osuTK.Graphics; using osu.Framework.Graphics.Shapes; +using osu.Game.Screens.Ranking.Types; namespace osu.Game.Screens.Ranking { - public class ResultModeButton : TabItem + public class ResultModeButton : TabItem { private readonly FontAwesome icon; private Color4 activeColour; private Color4 inactiveColour; private CircularContainer colouredPart; - public ResultModeButton(ResultMode mode) : base(mode) + public ResultModeButton(IResultType mode) + : base(mode) { - switch (mode) - { - case ResultMode.Summary: - icon = FontAwesome.fa_asterisk; - break; - case ResultMode.Ranking: - icon = FontAwesome.fa_list; - break; - case ResultMode.Share: - icon = FontAwesome.fa_camera; - break; - } + icon = mode.Icon; } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Ranking/ResultModeTabControl.cs b/osu.Game/Screens/Ranking/ResultModeTabControl.cs index e5c6115085..cc1f7bc6b2 100644 --- a/osu.Game/Screens/Ranking/ResultModeTabControl.cs +++ b/osu.Game/Screens/Ranking/ResultModeTabControl.cs @@ -3,11 +3,12 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; +using osu.Game.Screens.Ranking.Types; using osuTK; namespace osu.Game.Screens.Ranking { - public class ResultModeTabControl : TabControl + public class ResultModeTabControl : TabControl { public ResultModeTabControl() { @@ -19,9 +20,9 @@ namespace osu.Game.Screens.Ranking TabContainer.Padding = new MarginPadding(5); } - protected override Dropdown CreateDropdown() => null; + protected override Dropdown CreateDropdown() => null; - protected override TabItem CreateTabItem(ResultMode value) => new ResultModeButton(value) + protected override TabItem CreateTabItem(IResultType value) => new ResultModeButton(value) { Anchor = TabContainer.Anchor, Origin = TabContainer.Origin diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 1ff5fc7bfd..e7340b2c33 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.IEnumerableExtensions; @@ -18,12 +19,12 @@ using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Sprites; using osu.Game.Scoring; +using osu.Game.Screens.Ranking.Types; namespace osu.Game.Screens.Ranking { - public class Results : OsuScreen + public abstract class Results : OsuScreen { - private readonly ScoreInfo score; private Container circleOuterBackground; private Container circleOuter; private Container circleInner; @@ -34,6 +35,8 @@ namespace osu.Game.Screens.Ranking public override bool AllowBeatmapRulesetChange => false; + protected readonly ScoreInfo Score; + private Container currentPage; private static readonly Vector2 background_blur = new Vector2(20); @@ -44,9 +47,9 @@ namespace osu.Game.Screens.Ranking private const float circle_outer_scale = 0.96f; - public Results(ScoreInfo score) + protected Results(ScoreInfo score) { - this.score = score; + Score = score; } private const float transition_time = 800; @@ -67,7 +70,7 @@ namespace osu.Game.Screens.Ranking backgroundParallax.FadeOut(); modeChangeButtons.FadeOut(); - currentPage.FadeOut(); + currentPage?.FadeOut(); circleOuterBackground .FadeIn(transition_time, Easing.OutQuint) @@ -90,7 +93,7 @@ namespace osu.Game.Screens.Ranking using (BeginDelayedSequence(transition_time * 0.4f, true)) { modeChangeButtons.FadeIn(transition_time, Easing.OutQuint); - currentPage.FadeIn(transition_time, Easing.OutQuint); + currentPage?.FadeIn(transition_time, Easing.OutQuint); } } } @@ -188,7 +191,7 @@ namespace osu.Game.Screens.Ranking }, new OsuSpriteText { - Text = $"{score.MaxCombo}x", + Text = $"{Score.MaxCombo}x", TextSize = 40, RelativePositionAxes = Axes.X, Font = @"Exo2.0-Bold", @@ -209,7 +212,7 @@ namespace osu.Game.Screens.Ranking }, new OsuSpriteText { - Text = $"{score.Accuracy:P2}", + Text = $"{Score.Accuracy:P2}", TextSize = 40, RelativePositionAxes = Axes.X, Font = @"Exo2.0-Bold", @@ -262,30 +265,22 @@ namespace osu.Game.Screens.Ranking }, }; - modeChangeButtons.AddItem(ResultMode.Summary); - modeChangeButtons.AddItem(ResultMode.Ranking); - //modeChangeButtons.AddItem(ResultMode.Share); + foreach (var t in CreateResultTypes()) + modeChangeButtons.AddItem(t); + modeChangeButtons.Current.Value = modeChangeButtons.Items.FirstOrDefault(); - modeChangeButtons.Current.ValueChanged += mode => + modeChangeButtons.Current.BindValueChanged(m => { currentPage?.FadeOut(); currentPage?.Expire(); - switch (mode) - { - case ResultMode.Summary: - currentPage = new ResultsPageScore(score, Beatmap.Value); - break; - case ResultMode.Ranking: - currentPage = new ResultsPageRanking(score, Beatmap.Value); - break; - } + currentPage = m?.CreatePage(); if (currentPage != null) circleInner.Add(currentPage); - }; - - modeChangeButtons.Current.TriggerChange(); + }, true); } + + protected abstract IEnumerable CreateResultTypes(); } } diff --git a/osu.Game/Screens/Ranking/Types/IResultType.cs b/osu.Game/Screens/Ranking/Types/IResultType.cs new file mode 100644 index 0000000000..df574e99f1 --- /dev/null +++ b/osu.Game/Screens/Ranking/Types/IResultType.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Graphics; +using osu.Game.Screens.Ranking.Pages; + +namespace osu.Game.Screens.Ranking.Types +{ + public interface IResultType + { + FontAwesome Icon { get; } + + ResultsPage CreatePage(); + } +} diff --git a/osu.Game/Screens/Ranking/Types/RankingResultType.cs b/osu.Game/Screens/Ranking/Types/RankingResultType.cs new file mode 100644 index 0000000000..a11732d324 --- /dev/null +++ b/osu.Game/Screens/Ranking/Types/RankingResultType.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Scoring; +using osu.Game.Screens.Ranking.Pages; + +namespace osu.Game.Screens.Ranking.Types +{ + public class RankingResultType : IResultType + { + private readonly ScoreInfo score; + private readonly WorkingBeatmap beatmap; + + public RankingResultType(ScoreInfo score, WorkingBeatmap beatmap) + { + this.score = score; + this.beatmap = beatmap; + } + + public FontAwesome Icon => FontAwesome.fa_list; + + public ResultsPage CreatePage() => new RankingResultsPage(score, beatmap); + } +} diff --git a/osu.Game/Screens/Ranking/Types/ScoreResultType.cs b/osu.Game/Screens/Ranking/Types/ScoreResultType.cs new file mode 100644 index 0000000000..0841365528 --- /dev/null +++ b/osu.Game/Screens/Ranking/Types/ScoreResultType.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Scoring; +using osu.Game.Screens.Ranking.Pages; + +namespace osu.Game.Screens.Ranking.Types +{ + public class ScoreResultType : IResultType + { + private readonly ScoreInfo score; + private readonly WorkingBeatmap beatmap; + + public ScoreResultType(ScoreInfo score, WorkingBeatmap beatmap) + { + this.score = score; + this.beatmap = beatmap; + } + + public FontAwesome Icon => FontAwesome.fa_asterisk; + + public ResultsPage CreatePage() => new ScoreResultsPage(score, beatmap); + } +} diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 71b63c8e5b..f65cc0e49d 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -28,7 +28,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Edit; using osu.Game.Screens.Menu; -using osu.Game.Screens.Ranking; +using osu.Game.Screens.Play; using osu.Game.Screens.Select.Options; using osu.Game.Skinning; @@ -210,7 +210,7 @@ namespace osu.Game.Screens.Select }); } - BeatmapDetails.Leaderboard.ScoreSelected += s => Push(new Results(s)); + BeatmapDetails.Leaderboard.ScoreSelected += s => Push(new SoloResults(s)); } [BackgroundDependencyLoader(true)] From 4149734f89588a81494c9911f23e828aa2797cc7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 18:22:13 +0900 Subject: [PATCH 102/220] Add room leaderboard to results --- osu.Game.Tests/Visual/TestCaseMultiResults.cs | 47 +++++++++ .../Match/Components/MatchLeaderboard.cs | 8 +- osu.Game/Screens/Multi/Match/MatchScreen.cs | 2 +- .../Screens/Multi/Play/TimeshiftPlayer.cs | 15 ++- .../Screens/Multi/Ranking/MultiResults.cs | 30 ++++++ .../Ranking/Pages/RoomRankingResultsPage.cs | 96 +++++++++++++++++++ .../Ranking/Types/RoomRankingResultType.cs | 31 ++++++ osu.Game/Screens/Play/Player.cs | 5 +- 8 files changed, 226 insertions(+), 8 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseMultiResults.cs create mode 100644 osu.Game/Screens/Multi/Ranking/MultiResults.cs create mode 100644 osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs create mode 100644 osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs diff --git a/osu.Game.Tests/Visual/TestCaseMultiResults.cs b/osu.Game.Tests/Visual/TestCaseMultiResults.cs new file mode 100644 index 0000000000..53172b588c --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMultiResults.cs @@ -0,0 +1,47 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Scoring; +using osu.Game.Screens.Multi.Ranking; +using osu.Game.Screens.Multi.Ranking.Pages; +using osu.Game.Screens.Multi.Ranking.Types; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseMultiResults : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(MultiResults), + typeof(RoomRankingResultType), + typeof(RoomRankingResultsPage) + }; + + [Resolved] + private BeatmapManager beatmaps { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0); + if (beatmapInfo != null) + Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo); + + MultiResults res; + + Child = res = new MultiResults(new ScoreInfo + { + User = new User + { + Id = 9623649 + }, + }, new Room { RoomID = { Value = 46 } }); + } + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 9d4ad3cb22..4b09349be5 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -18,6 +18,8 @@ namespace osu.Game.Screens.Multi.Match.Components { public class MatchLeaderboard : Leaderboard { + public Action> ScoresLoaded; + private readonly Room room; public MatchLeaderboard(Room room) @@ -42,7 +44,11 @@ namespace osu.Game.Screens.Multi.Match.Components var req = new GetRoomScoresRequest(room.RoomID.Value ?? 0); - req.Success += r => scoresCallback?.Invoke(r); + req.Success += r => + { + scoresCallback?.Invoke(r); + ScoresLoaded?.Invoke(r); + }; return req; } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index b865c07e31..dfedf6d7a1 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -174,7 +174,7 @@ namespace osu.Game.Screens.Multi.Match { default: case GameTypeTimeshift _: - var player = new TimeshiftPlayer(room.RoomID.Value ?? 0, room.Playlist.First().ID); + var player = new TimeshiftPlayer(room, room.Playlist.First().ID); player.Exited += _ => leaderboard.RefreshScores(); pushGameplayScreen?.Invoke(new PlayerLoader(player)); diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index 5d45615aa8..8e40544ccc 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -9,22 +9,25 @@ using osu.Framework.Allocation; using osu.Framework.IO.Network; using osu.Framework.Logging; using osu.Game.Online.API; +using osu.Game.Online.Multiplayer; using osu.Game.Scoring; +using osu.Game.Screens.Multi.Ranking; using osu.Game.Screens.Play; +using osu.Game.Screens.Ranking; namespace osu.Game.Screens.Multi.Play { public class TimeshiftPlayer : Player { - private readonly int roomId; + private readonly Room room; private readonly int playlistItemId; [Resolved] private APIAccess api { get; set; } - public TimeshiftPlayer(int roomId, int playlistItemId) + public TimeshiftPlayer(Room room, int playlistItemId) { - this.roomId = roomId; + this.room = room; this.playlistItemId = playlistItemId; } @@ -37,7 +40,7 @@ namespace osu.Game.Screens.Multi.Play bool failed = false; - var req = new CreateScoreRequest(roomId, playlistItemId); + var req = new CreateScoreRequest(room.RoomID.Value ?? 0, playlistItemId); req.Success += r => token = r.ID; req.Failure += e => { @@ -64,12 +67,14 @@ namespace osu.Game.Screens.Multi.Play Debug.Assert(token != null); - var request = new SubmitScoreRequest(token.Value, roomId, playlistItemId, score); + var request = new SubmitScoreRequest(token.Value, room.RoomID.Value ?? 0, playlistItemId, score); request.Failure += e => Logger.Error(e, "Failed to submit score"); api.Queue(request); return score; } + + protected override Results CreateResults(ScoreInfo score) => new MultiResults(score, room); } public class SubmitScoreRequest : APIRequest diff --git a/osu.Game/Screens/Multi/Ranking/MultiResults.cs b/osu.Game/Screens/Multi/Ranking/MultiResults.cs new file mode 100644 index 0000000000..4358943057 --- /dev/null +++ b/osu.Game/Screens/Multi/Ranking/MultiResults.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Online.Multiplayer; +using osu.Game.Scoring; +using osu.Game.Screens.Multi.Ranking.Types; +using osu.Game.Screens.Ranking; +using osu.Game.Screens.Ranking.Types; + +namespace osu.Game.Screens.Multi.Ranking +{ + public class MultiResults : Results + { + private readonly Room room; + + public MultiResults(ScoreInfo score, Room room) + : base(score) + { + this.room = room; + } + + protected override IEnumerable CreateResultTypes() => new IResultType[] + { + new ScoreResultType(Score, Beatmap), + new RankingResultType(Score, Beatmap), + new RoomRankingResultType(Score, Beatmap, room), + }; + } +} diff --git a/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs b/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs new file mode 100644 index 0000000000..64c7d73322 --- /dev/null +++ b/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs @@ -0,0 +1,96 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Internal; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Lists; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Online.Leaderboards; +using osu.Game.Online.Multiplayer; +using osu.Game.Scoring; +using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Screens.Ranking.Pages; + +namespace osu.Game.Screens.Multi.Ranking.Pages +{ + public class RoomRankingResultsPage : ResultsPage + { + private readonly Room room; + + private OsuColour colours; + + private TextFlowContainer rankText; + + public RoomRankingResultsPage(ScoreInfo score, WorkingBeatmap beatmap, Room room) + : base(score, beatmap) + { + this.room = room; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + this.colours = colours; + + Children = new Drawable[] + { + new Box + { + Colour = colours.GrayE, + RelativeSizeAxes = Axes.Both, + }, + new BufferedContainer + { + RelativeSizeAxes = Axes.Both, + BackgroundColour = colours.GrayE, + Children = new Drawable[] + { + new MatchLeaderboard(room) + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.8f, + Y = 95, + ScoresLoaded = scoresLoaded + } + } + }, + rankText = new TextFlowContainer + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Width = 0.5f, + AutoSizeAxes = Axes.Y, + Y = 75, + TextAnchor = Anchor.TopCentre + }, + }; + } + + private void scoresLoaded(IEnumerable scores) + { + Action gray = s => s.Colour = colours.Gray8; + + rankText.AddText("You are placed ", gray); + + int index = scores.IndexOf(new RoomScore { User = Score.User }, new FuncEqualityComparer((s1, s2) => s1.User.Id.Equals(s2.User.Id))); + + rankText.AddText($"#{index + 1} ", s => + { + s.Font = "Exo2.0-Bold"; + s.Colour = colours.YellowDark; + }); + + rankText.AddText("in the room!", gray); + } + } +} diff --git a/osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs b/osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs new file mode 100644 index 0000000000..378b650ea7 --- /dev/null +++ b/osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Online.Multiplayer; +using osu.Game.Scoring; +using osu.Game.Screens.Multi.Ranking.Pages; +using osu.Game.Screens.Ranking.Pages; +using osu.Game.Screens.Ranking.Types; + +namespace osu.Game.Screens.Multi.Ranking.Types +{ + public class RoomRankingResultType : IResultType + { + private readonly ScoreInfo score; + private readonly WorkingBeatmap beatmap; + private readonly Room room; + + public RoomRankingResultType(ScoreInfo score, WorkingBeatmap beatmap, Room room) + { + this.score = score; + this.beatmap = beatmap; + this.room = room; + } + + public FontAwesome Icon => FontAwesome.fa_list; + + public ResultsPage CreatePage() => new RoomRankingResultsPage(score, beatmap, room); + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 1429675ddd..f2390318b0 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -28,6 +28,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; +using osu.Game.Screens.Ranking; using osu.Game.Skinning; using osu.Game.Storyboards.Drawables; @@ -287,7 +288,7 @@ namespace osu.Game.Screens.Play if (RulesetContainer.Replay == null) scoreManager.Import(score, true); - Push(new SoloResults(score)); + Push(CreateResults(score)); onCompletionEvent = null; }); @@ -431,5 +432,7 @@ namespace osu.Game.Screens.Play if (storyboardVisible && beatmap.Storyboard.ReplacesBackground) Background?.FadeTo(0, BACKGROUND_FADE_DURATION, Easing.OutQuint); } + + protected virtual Results CreateResults(ScoreInfo score) => new SoloResults(score); } } From 7e9cc4e8766160bb8a86099e9d702b867d6508aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 18:37:33 +0900 Subject: [PATCH 103/220] Seed the results screen --- osu.Game.Tests/Visual/TestCaseMultiResults.cs | 93 +++++++++++++++++-- .../Ranking/Pages/RoomRankingResultsPage.cs | 25 +++-- .../Ranking/Types/RoomRankingResultType.cs | 2 +- 3 files changed, 98 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMultiResults.cs b/osu.Game.Tests/Visual/TestCaseMultiResults.cs index 53172b588c..988ba0efdc 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiResults.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiResults.cs @@ -3,13 +3,18 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Game.Beatmaps; +using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Scoring; +using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Ranking; using osu.Game.Screens.Multi.Ranking.Pages; using osu.Game.Screens.Multi.Ranking.Types; +using osu.Game.Screens.Ranking.Pages; +using osu.Game.Screens.Ranking.Types; using osu.Game.Users; namespace osu.Game.Tests.Visual @@ -33,15 +38,87 @@ namespace osu.Game.Tests.Visual if (beatmapInfo != null) Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo); - MultiResults res; - - Child = res = new MultiResults(new ScoreInfo + Child = new TestMultiResults(new ScoreInfo { - User = new User - { - Id = 9623649 - }, - }, new Room { RoomID = { Value = 46 } }); + User = new User { Id = 10 }, + }); + } + + private class TestMultiResults : MultiResults + { + private readonly Room room; + + public TestMultiResults(ScoreInfo score) + : this(score, new Room()) + { + } + + public TestMultiResults(ScoreInfo score, Room room) + : base(score, room) + { + this.room = room; + } + + protected override IEnumerable CreateResultTypes() => new IResultType[] + { + new ScoreResultType(Score, Beatmap), + new RankingResultType(Score, Beatmap), + new TestRoomRankingResultType(Score, Beatmap, room), + }; + } + + private class TestRoomRankingResultType : RoomRankingResultType + { + private readonly ScoreInfo score; + private readonly WorkingBeatmap beatmap; + private readonly Room room; + + public TestRoomRankingResultType(ScoreInfo score, WorkingBeatmap beatmap, Room room) + : base(score, beatmap, room) + { + this.score = score; + this.beatmap = beatmap; + this.room = room; + } + + public override ResultsPage CreatePage() => new TestRoomRankingResultsPage(score, beatmap, room); + } + + private class TestRoomRankingResultsPage : RoomRankingResultsPage + { + public TestRoomRankingResultsPage(ScoreInfo score, WorkingBeatmap beatmap, Room room) + : base(score, beatmap, room) + { + } + + protected override MatchLeaderboard CreateLeaderboard(Room room) => new TestMatchLeaderboard(room); + } + + private class TestMatchLeaderboard : MatchLeaderboard + { + public TestMatchLeaderboard(Room room) + : base(room) + { + } + + protected override APIRequest FetchScores(Action> scoresCallback) + { + var scores = Enumerable.Range(0, 50).Select(createRoomScore).ToArray(); + + scoresCallback?.Invoke(scores); + ScoresLoaded?.Invoke(scores); + + return null; + } + + private RoomScore createRoomScore(int id) => new RoomScore + { + User = new User { Id = id, Username = $"User {id}" }, + Accuracy = 0.98, + TotalScore = 987654, + TotalAttempts = 13, + CompletedAttempts = 5 + }; } } } diff --git a/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs b/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs index 64c7d73322..6c46973ca7 100644 --- a/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs +++ b/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Lists; using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Online.Leaderboards; using osu.Game.Online.Multiplayer; using osu.Game.Scoring; using osu.Game.Screens.Multi.Match.Components; @@ -39,6 +38,8 @@ namespace osu.Game.Screens.Multi.Ranking.Pages { this.colours = colours; + MatchLeaderboard leaderboard; + Children = new Drawable[] { new Box @@ -50,18 +51,7 @@ namespace osu.Game.Screens.Multi.Ranking.Pages { RelativeSizeAxes = Axes.Both, BackgroundColour = colours.GrayE, - Children = new Drawable[] - { - new MatchLeaderboard(room) - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Height = 0.8f, - Y = 95, - ScoresLoaded = scoresLoaded - } - } + Child = leaderboard = CreateLeaderboard(room) }, rankText = new TextFlowContainer { @@ -74,6 +64,13 @@ namespace osu.Game.Screens.Multi.Ranking.Pages TextAnchor = Anchor.TopCentre }, }; + + leaderboard.Origin = Anchor.Centre; + leaderboard.Anchor = Anchor.Centre; + leaderboard.RelativeSizeAxes = Axes.Both; + leaderboard.Height = 0.8f; + leaderboard.Y = 95; + leaderboard.ScoresLoaded = scoresLoaded; } private void scoresLoaded(IEnumerable scores) @@ -92,5 +89,7 @@ namespace osu.Game.Screens.Multi.Ranking.Pages rankText.AddText("in the room!", gray); } + + protected virtual MatchLeaderboard CreateLeaderboard(Room room) => new MatchLeaderboard(room); } } diff --git a/osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs b/osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs index 378b650ea7..963a9ff1cf 100644 --- a/osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs +++ b/osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs @@ -26,6 +26,6 @@ namespace osu.Game.Screens.Multi.Ranking.Types public FontAwesome Icon => FontAwesome.fa_list; - public ResultsPage CreatePage() => new RoomRankingResultsPage(score, beatmap, room); + public virtual ResultsPage CreatePage() => new RoomRankingResultsPage(score, beatmap, room); } } From dd0c04ea366ff94b72a6d562c759960bb733d631 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 12:45:36 +0900 Subject: [PATCH 104/220] Move RoomManager to multiplayer screen --- osu.Game/Screens/Multi/Lounge/LoungeScreen.cs | 27 ++++++++++++++----- osu.Game/Screens/Multi/Multiplayer.cs | 6 ++++- osu.Game/Screens/Multi/RoomManager.cs | 2 +- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index 562dfaa347..a6d4d845e0 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -22,8 +22,8 @@ namespace osu.Game.Screens.Multi.Lounge private readonly RoomsContainer rooms; private readonly Action pushGameplayScreen; - [Cached] - private readonly RoomManager manager; + [Resolved] + private RoomManager roomManager { get; set; } public override string Title => "Lounge"; @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Multi.Lounge { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = rooms = new RoomsContainer { JoinRequested = r => manager?.JoinRoom(r) } + Child = rooms = new RoomsContainer { JoinRequested = r => roomManager?.JoinRoom(r) } }, }, inspector = new RoomInspector @@ -68,7 +68,6 @@ namespace osu.Game.Screens.Multi.Lounge }, }, }, - manager = new RoomManager { OpenRequested = Open } }; inspector.Room.BindTo(rooms.SelectedRoom); @@ -78,6 +77,12 @@ namespace osu.Game.Screens.Multi.Lounge Filter.Search.Exit += Exit; } + [BackgroundDependencyLoader] + private void load() + { + roomManager.OpenRequested += Open; + } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -103,7 +108,7 @@ namespace osu.Game.Screens.Multi.Lounge protected override bool OnExiting(Screen next) { - manager?.PartRoom(); + roomManager?.PartRoom(); Filter.Search.HoldFocus = false; return base.OnExiting(next); @@ -111,7 +116,7 @@ namespace osu.Game.Screens.Multi.Lounge protected override void OnResuming(Screen last) { - manager?.PartRoom(); + roomManager?.PartRoom(); base.OnResuming(last); } @@ -125,7 +130,7 @@ namespace osu.Game.Screens.Multi.Lounge private void filterRooms() { rooms.Filter(Filter.CreateCriteria()); - manager.Filter(Filter.CreateCriteria()); + roomManager.Filter(Filter.CreateCriteria()); } public void Open(Room room) @@ -136,5 +141,13 @@ namespace osu.Game.Screens.Multi.Lounge Push(new MatchScreen(room, s => pushGameplayScreen?.Invoke(s))); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (roomManager != null) + roomManager.OpenRequested -= Open; + } } } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 9339c6693f..116d4137d5 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -31,6 +31,9 @@ namespace osu.Game.Screens.Multi private OsuScreen currentScreen; + [Cached] + private RoomManager roomManager; + public Multiplayer() { Child = waves = new MultiplayerWaveContainer @@ -80,7 +83,8 @@ namespace osu.Game.Screens.Multi }, Text = "Create room", Action = () => loungeScreen.Open(new Room()) - } + }, + roomManager = new RoomManager() }); screenAdded(loungeScreen); diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index b3bb9cb147..dbc0fd3491 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Multi { public class RoomManager : PollingComponent { - public Action OpenRequested; + public event Action OpenRequested; public IBindableCollection Rooms => rooms; private readonly BindableCollection rooms = new BindableCollection(); From 1cb69c3478b91cc9a31c197bafc79102b3d5768e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 12:50:37 +0900 Subject: [PATCH 105/220] Split requests/responses into separate files --- .../Online/API/Requests/CreateRoomRequest.cs | 34 ++++++ .../API/Requests/CreateRoomScoreRequest.cs | 30 +++++ .../Online/API/Requests/GetRoomsRequest.cs | 44 +++++++ .../Online/API/Requests/JoinRoomRequest.cs | 31 +++++ .../Online/API/Requests/PartRoomRequest.cs | 31 +++++ .../API/Requests/Responses/APIRoomScore.cs | 13 +++ .../API/Requests/SubmitRoomScoreRequest.cs | 40 +++++++ .../Screens/Multi/Play/TimeshiftPlayer.cs | 65 +---------- osu.Game/Screens/Multi/RoomManager.cs | 107 +----------------- 9 files changed, 227 insertions(+), 168 deletions(-) create mode 100644 osu.Game/Online/API/Requests/CreateRoomRequest.cs create mode 100644 osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs create mode 100644 osu.Game/Online/API/Requests/GetRoomsRequest.cs create mode 100644 osu.Game/Online/API/Requests/JoinRoomRequest.cs create mode 100644 osu.Game/Online/API/Requests/PartRoomRequest.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIRoomScore.cs create mode 100644 osu.Game/Online/API/Requests/SubmitRoomScoreRequest.cs diff --git a/osu.Game/Online/API/Requests/CreateRoomRequest.cs b/osu.Game/Online/API/Requests/CreateRoomRequest.cs new file mode 100644 index 0000000000..7ce289b65a --- /dev/null +++ b/osu.Game/Online/API/Requests/CreateRoomRequest.cs @@ -0,0 +1,34 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Net.Http; +using Newtonsoft.Json; +using osu.Framework.IO.Network; +using osu.Game.Online.Multiplayer; + +namespace osu.Game.Online.API.Requests +{ + public class CreateRoomRequest : APIRequest + { + private readonly Room room; + + public CreateRoomRequest(Room room) + { + this.room = room; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + + req.ContentType = "application/json"; + req.Method = HttpMethod.Post; + + req.AddRaw(JsonConvert.SerializeObject(room)); + + return req; + } + + protected override string Target => "rooms"; + } +} diff --git a/osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs b/osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs new file mode 100644 index 0000000000..99640f435e --- /dev/null +++ b/osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Net.Http; +using osu.Framework.IO.Network; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class CreateRoomScoreRequest : APIRequest + { + private readonly int roomId; + private readonly int playlistItemId; + + public CreateRoomScoreRequest(int roomId, int playlistItemId) + { + this.roomId = roomId; + this.playlistItemId = playlistItemId; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + return req; + } + + protected override string Target => $@"rooms/{roomId}/playlist/{playlistItemId}/scores"; + } +} diff --git a/osu.Game/Online/API/Requests/GetRoomsRequest.cs b/osu.Game/Online/API/Requests/GetRoomsRequest.cs new file mode 100644 index 0000000000..bc835b1ab4 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetRoomsRequest.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Lounge.Components; + +namespace osu.Game.Online.API.Requests +{ + public class GetRoomsRequest : APIRequest> + { + private readonly PrimaryFilter primaryFilter; + + public GetRoomsRequest(PrimaryFilter primaryFilter) + { + this.primaryFilter = primaryFilter; + } + + protected override string Target + { + get + { + string target = "rooms"; + + switch (primaryFilter) + { + case PrimaryFilter.Open: + break; + case PrimaryFilter.Owned: + target += "/owned"; + break; + case PrimaryFilter.Participated: + target += "/participated"; + break; + case PrimaryFilter.RecentlyEnded: + target += "/ended"; + break; + } + + return target; + } + } + } +} diff --git a/osu.Game/Online/API/Requests/JoinRoomRequest.cs b/osu.Game/Online/API/Requests/JoinRoomRequest.cs new file mode 100644 index 0000000000..b5e162da08 --- /dev/null +++ b/osu.Game/Online/API/Requests/JoinRoomRequest.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Net.Http; +using osu.Framework.IO.Network; +using osu.Game.Online.Multiplayer; +using osu.Game.Users; + +namespace osu.Game.Online.API.Requests +{ + public class JoinRoomRequest : APIRequest + { + private readonly Room room; + private readonly User user; + + public JoinRoomRequest(Room room, User user) + { + this.room = room; + this.user = user; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Put; + return req; + } + + protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}"; + } +} diff --git a/osu.Game/Online/API/Requests/PartRoomRequest.cs b/osu.Game/Online/API/Requests/PartRoomRequest.cs new file mode 100644 index 0000000000..5e4457f69f --- /dev/null +++ b/osu.Game/Online/API/Requests/PartRoomRequest.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Net.Http; +using osu.Framework.IO.Network; +using osu.Game.Online.Multiplayer; +using osu.Game.Users; + +namespace osu.Game.Online.API.Requests +{ + public class PartRoomRequest : APIRequest + { + private readonly Room room; + private readonly User user; + + public PartRoomRequest(Room room, User user) + { + this.room = room; + this.user = user; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Delete; + return req; + } + + protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}"; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIRoomScore.cs b/osu.Game/Online/API/Requests/Responses/APIRoomScore.cs new file mode 100644 index 0000000000..9bf67836f6 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIRoomScore.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIRoomScore + { + [JsonProperty("id")] + public int ID { get; set; } + } +} diff --git a/osu.Game/Online/API/Requests/SubmitRoomScoreRequest.cs b/osu.Game/Online/API/Requests/SubmitRoomScoreRequest.cs new file mode 100644 index 0000000000..d25e35db58 --- /dev/null +++ b/osu.Game/Online/API/Requests/SubmitRoomScoreRequest.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Net.Http; +using Newtonsoft.Json; +using osu.Framework.IO.Network; +using osu.Game.Scoring; + +namespace osu.Game.Online.API.Requests +{ + public class SubmitRoomScoreRequest : APIRequest + { + private readonly int scoreId; + private readonly int roomId; + private readonly int playlistItemId; + private readonly ScoreInfo scoreInfo; + + public SubmitRoomScoreRequest(int scoreId, int roomId, int playlistItemId, ScoreInfo scoreInfo) + { + this.scoreId = scoreId; + this.roomId = roomId; + this.playlistItemId = playlistItemId; + this.scoreInfo = scoreInfo; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + + req.ContentType = "application/json"; + req.Method = HttpMethod.Put; + + req.AddRaw(JsonConvert.SerializeObject(scoreInfo)); + + return req; + } + + protected override string Target => $@"rooms/{roomId}/playlist/{playlistItemId}/scores/{scoreId}"; + } +} diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index 8e40544ccc..f33159f69b 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -2,13 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Diagnostics; -using System.Net.Http; using System.Threading; -using Newtonsoft.Json; using osu.Framework.Allocation; -using osu.Framework.IO.Network; using osu.Framework.Logging; using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.Multiplayer; using osu.Game.Scoring; using osu.Game.Screens.Multi.Ranking; @@ -40,7 +38,7 @@ namespace osu.Game.Screens.Multi.Play bool failed = false; - var req = new CreateScoreRequest(room.RoomID.Value ?? 0, playlistItemId); + var req = new CreateRoomScoreRequest(room.RoomID.Value ?? 0, playlistItemId); req.Success += r => token = r.ID; req.Failure += e => { @@ -67,7 +65,7 @@ namespace osu.Game.Screens.Multi.Play Debug.Assert(token != null); - var request = new SubmitScoreRequest(token.Value, room.RoomID.Value ?? 0, playlistItemId, score); + var request = new SubmitRoomScoreRequest(token.Value, room.RoomID.Value ?? 0, playlistItemId, score); request.Failure += e => Logger.Error(e, "Failed to submit score"); api.Queue(request); @@ -76,61 +74,4 @@ namespace osu.Game.Screens.Multi.Play protected override Results CreateResults(ScoreInfo score) => new MultiResults(score, room); } - - public class SubmitScoreRequest : APIRequest - { - private readonly int scoreId; - private readonly int roomId; - private readonly int playlistItemId; - private readonly ScoreInfo scoreInfo; - - public SubmitScoreRequest(int scoreId, int roomId, int playlistItemId, ScoreInfo scoreInfo) - { - this.scoreId = scoreId; - this.roomId = roomId; - this.playlistItemId = playlistItemId; - this.scoreInfo = scoreInfo; - } - - protected override WebRequest CreateWebRequest() - { - var req = base.CreateWebRequest(); - - req.ContentType = "application/json"; - req.Method = HttpMethod.Put; - - req.AddRaw(JsonConvert.SerializeObject(scoreInfo)); - - return req; - } - - protected override string Target => $@"rooms/{roomId}/playlist/{playlistItemId}/scores/{scoreId}"; - } - - public class CreateScoreRequest : APIRequest - { - private readonly int roomId; - private readonly int playlistItemId; - - public CreateScoreRequest(int roomId, int playlistItemId) - { - this.roomId = roomId; - this.playlistItemId = playlistItemId; - } - - protected override WebRequest CreateWebRequest() - { - var req = base.CreateWebRequest(); - req.Method = HttpMethod.Post; - return req; - } - - protected override string Target => $@"rooms/{roomId}/playlist/{playlistItemId}/scores"; - } - - public class CreateScoreResult - { - [JsonProperty("id")] - public int ID { get; set; } - } } diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index dbc0fd3491..17c3229b1a 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -2,22 +2,18 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using System.Linq; -using System.Net.Http; using System.Threading.Tasks; -using Newtonsoft.Json; using osu.Framework.Allocation; using osu.Framework.Configuration; -using osu.Framework.IO.Network; using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Online; using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; using osu.Game.Screens.Multi.Lounge.Components; -using osu.Game.Users; namespace osu.Game.Screens.Multi { @@ -148,106 +144,5 @@ namespace osu.Game.Screens.Multi foreach (var pi in room.Playlist) pi.MapObjects(beatmaps, rulesets); } - - private class CreateRoomRequest : APIRequest - { - private readonly Room room; - - public CreateRoomRequest(Room room) - { - this.room = room; - } - - protected override WebRequest CreateWebRequest() - { - var req = base.CreateWebRequest(); - - req.ContentType = "application/json"; - req.Method = HttpMethod.Post; - - req.AddRaw(JsonConvert.SerializeObject(room)); - - return req; - } - - protected override string Target => "rooms"; - } - - private class JoinRoomRequest : APIRequest - { - private readonly Room room; - private readonly User user; - - public JoinRoomRequest(Room room, User user) - { - this.room = room; - this.user = user; - } - - protected override WebRequest CreateWebRequest() - { - var req = base.CreateWebRequest(); - req.Method = HttpMethod.Put; - return req; - } - - protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}"; - } - - private class PartRoomRequest : APIRequest - { - private readonly Room room; - private readonly User user; - - public PartRoomRequest(Room room, User user) - { - this.room = room; - this.user = user; - } - - protected override WebRequest CreateWebRequest() - { - var req = base.CreateWebRequest(); - req.Method = HttpMethod.Delete; - return req; - } - - protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}"; - } - - private class GetRoomsRequest : APIRequest> - { - private readonly PrimaryFilter primaryFilter; - - public GetRoomsRequest(PrimaryFilter primaryFilter) - { - this.primaryFilter = primaryFilter; - } - - protected override string Target - { - get - { - string target = "rooms"; - - switch (primaryFilter) - { - case PrimaryFilter.Open: - break; - case PrimaryFilter.Owned: - target += "/owned"; - break; - case PrimaryFilter.Participated: - target += "/participated"; - break; - case PrimaryFilter.RecentlyEnded: - target += "/ended"; - break; - } - - return target; - } - } - } } } From f1a9a352fceba6a1a98c3e943daf529bff8048f8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 14:01:06 +0900 Subject: [PATCH 106/220] Cleanup bindable handling --- osu.Game.Tests/Visual/TestCaseMatchInfo.cs | 64 ++++++----- .../Visual/TestCaseMatchParticipants.cs | 24 +++-- .../Screens/Multi/Components/BeatmapTitle.cs | 30 +++--- .../Multi/Components/ParticipantCount.cs | 4 +- .../Multi/Lounge/Components/DrawableRoom.cs | 60 +++-------- .../Lounge/Components/ParticipantInfo.cs | 4 +- .../Multi/Lounge/Components/RoomInspector.cs | 73 +++---------- .../Screens/Multi/Match/Components/Header.cs | 8 +- .../Screens/Multi/Match/Components/Info.cs | 10 +- .../Multi/Match/Components/Participants.cs | 10 +- .../Match/Components/RoomSettingsOverlay.cs | 50 +++------ osu.Game/Screens/Multi/Match/MatchScreen.cs | 100 ++++++++--------- osu.Game/Screens/Multi/RoomBindings.cs | 101 ++++++++++++++++++ 13 files changed, 269 insertions(+), 269 deletions(-) create mode 100644 osu.Game/Screens/Multi/RoomBindings.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs index 0d3c769dc5..be3367bf6c 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs @@ -26,38 +26,54 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - Info info = new Info(new Room()); + var room = new Room(); + + Info info = new Info(room); Add(info); - AddStep(@"set name", () => info.Name.Value = @"Room Name?"); - AddStep(@"set availability", () => info.Availability.Value = RoomAvailability.FriendsOnly); - AddStep(@"set status", () => info.Status.Value = new RoomStatusPlaying()); - AddStep(@"set beatmap", () => info.Beatmap.Value = new BeatmapInfo + AddStep(@"set name", () => room.Name.Value = @"Room Name?"); + AddStep(@"set availability", () => room.Availability.Value = RoomAvailability.FriendsOnly); + AddStep(@"set status", () => room.Status.Value = new RoomStatusPlaying()); + AddStep(@"set beatmap", () => { - StarDifficulty = 2.4, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata + room.Playlist.Clear(); + room.Playlist.Add(new PlaylistItem { - Title = @"My Song", - Artist = @"VisualTests", - AuthorString = @"osu!lazer", - }, + Beatmap = new BeatmapInfo + { + StarDifficulty = 2.4, + Ruleset = rulesets.GetRuleset(0), + Metadata = new BeatmapMetadata + { + Title = @"My Song", + Artist = @"VisualTests", + AuthorString = @"osu!lazer", + }, + } + }); }); - AddStep(@"change name", () => info.Name.Value = @"Room Name!"); - AddStep(@"change availability", () => info.Availability.Value = RoomAvailability.InviteOnly); - AddStep(@"change status", () => info.Status.Value = new RoomStatusOpen()); - AddStep(@"null beatmap", () => info.Beatmap.Value = null); - AddStep(@"change beatmap", () => info.Beatmap.Value = new BeatmapInfo + AddStep(@"change name", () => room.Name.Value = @"Room Name!"); + AddStep(@"change availability", () => room.Availability.Value = RoomAvailability.InviteOnly); + AddStep(@"change status", () => room.Status.Value = new RoomStatusOpen()); + AddStep(@"null beatmap", () => room.Playlist.Clear()); + AddStep(@"change beatmap", () => { - StarDifficulty = 4.2, - Ruleset = rulesets.GetRuleset(3), - Metadata = new BeatmapMetadata + room.Playlist.Clear(); + room.Playlist.Add(new PlaylistItem { - Title = @"Your Song", - Artist = @"Tester", - AuthorString = @"Someone", - }, + Beatmap = new BeatmapInfo + { + StarDifficulty = 4.2, + Ruleset = rulesets.GetRuleset(3), + Metadata = new BeatmapMetadata + { + Title = @"Your Song", + Artist = @"Tester", + AuthorString = @"Someone", + }, + } + }); }); } } diff --git a/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs index 67a56e525f..27aeb9b5eb 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs @@ -1,7 +1,9 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Users; @@ -11,16 +13,20 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseMatchParticipants : OsuTestCase { + private readonly Bindable maxParticipants = new Bindable(); + private readonly Bindable> users = new Bindable>(); + public TestCaseMatchParticipants() { Participants participants; - Add(participants = new Participants - { - RelativeSizeAxes = Axes.Both, - }); - AddStep(@"set max to null", () => participants.MaxParticipants.Value = null); - AddStep(@"set users", () => participants.Users.Value = new[] + Add(participants = new Participants { RelativeSizeAxes = Axes.Both }); + + participants.MaxParticipants.BindTo(maxParticipants); + participants.Users.BindTo(users); + + AddStep(@"set max to null", () => maxParticipants.Value = null); + AddStep(@"set users", () => users.Value = new[] { new User { @@ -48,9 +54,9 @@ namespace osu.Game.Tests.Visual }, }); - AddStep(@"set max", () => participants.MaxParticipants.Value = 10); - AddStep(@"clear users", () => participants.Users.Value = new User[] { }); - AddStep(@"set max to null", () => participants.MaxParticipants.Value = null); + AddStep(@"set max", () => maxParticipants.Value = 10); + AddStep(@"clear users", () => users.Value = new User[] { }); + AddStep(@"set max to null", () => maxParticipants.Value = null); } } } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index 67d414a080..d609f7a70d 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs @@ -14,21 +14,6 @@ namespace osu.Game.Screens.Multi.Components { public class BeatmapTitle : CompositeDrawable { - private float textSize = OsuSpriteText.FONT_SIZE; - - public float TextSize - { - get => textSize; - set - { - if (textSize == value) - return; - textSize = value; - - updateText(); - } - } - public readonly IBindable Beatmap = new Bindable(); private readonly LinkFlowContainer textFlow; @@ -48,6 +33,21 @@ namespace osu.Game.Screens.Multi.Components updateText(); } + private float textSize = OsuSpriteText.FONT_SIZE; + + public float TextSize + { + get => textSize; + set + { + if (textSize == value) + return; + textSize = value; + + updateText(); + } + } + private void updateText() { if (!IsLoaded) diff --git a/osu.Game/Screens/Multi/Components/ParticipantCount.cs b/osu.Game/Screens/Multi/Components/ParticipantCount.cs index 66f13ed683..8665678562 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantCount.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantCount.cs @@ -18,8 +18,8 @@ namespace osu.Game.Screens.Multi.Components private readonly OsuSpriteText slash, maxText; - public readonly Bindable> Participants = new Bindable>(); - public readonly Bindable MaxParticipants = new Bindable(); + public readonly IBindable> Participants = new Bindable>(); + public readonly IBindable MaxParticipants = new Bindable(); public ParticipantCount() { diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index f4e304d0a8..d6bc0018e4 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -3,10 +3,8 @@ using System; using System.Collections.Generic; -using System.Linq; using osu.Framework; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -19,7 +17,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Components; -using osu.Game.Users; using osuTK; using osuTK.Graphics; @@ -37,18 +34,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components public event Action StateChanged; + private readonly RoomBindings bindings = new RoomBindings(); + private readonly Box selectionBox; - - private readonly Bindable nameBind = new Bindable(); - private readonly Bindable hostBind = new Bindable(); - private readonly Bindable statusBind = new Bindable(); - private readonly Bindable typeBind = new Bindable(); - private readonly Bindable> participantsBind = new Bindable>(); - private readonly IBindableCollection playlistBind = new BindableCollection(); - private readonly IBindable endDateBind = new Bindable(); - - private readonly Bindable beatmap = new Bindable(); - private UpdateableBeatmapBackgroundSprite background; private BeatmapTitle beatmapTitle; private ModeTypeInfo modeTypeInfo; @@ -92,6 +80,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components public DrawableRoom(Room room) { Room = room; + bindings.Room = room; RelativeSizeAxes = Axes.X; Height = height + SELECTION_BORDER_WIDTH * 2; @@ -222,7 +211,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components }, }; - statusBind.ValueChanged += s => + bindings.Status.ValueChanged += s => { status.Text = s.Message; @@ -230,31 +219,15 @@ namespace osu.Game.Screens.Multi.Lounge.Components d.FadeColour(s.GetAppropriateColour(colours), transition_duration); }; - nameBind.BindValueChanged(n => name.Text = n); + background.Beatmap.BindTo(bindings.CurrentBeatmap); + modeTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); + beatmapTitle.Beatmap.BindTo(bindings.CurrentBeatmap); + modeTypeInfo.Type.BindTo(bindings.Type); + participantInfo.Host.BindTo(bindings.Host); + participantInfo.Participants.BindTo(bindings.Participants); - nameBind.BindTo(Room.Name); - hostBind.BindTo(Room.Host); - statusBind.BindTo(Room.Status); - typeBind.BindTo(Room.Type); - playlistBind.BindTo(Room.Playlist); - participantsBind.BindTo(Room.Participants); - endDateBind.BindTo(Room.EndDate); - - endDateBind.BindValueChanged(d => endDate.Date = d, true); - - background.Beatmap.BindTo(beatmap); - modeTypeInfo.Beatmap.BindTo(beatmap); - beatmapTitle.Beatmap.BindTo(beatmap); - - modeTypeInfo.Type.BindTo(typeBind); - - participantInfo.Host.BindTo(hostBind); - participantInfo.Participants.BindTo(participantsBind); - - playlistBind.ItemsAdded += _ => updatePlaylist(); - playlistBind.ItemsRemoved += _ => updatePlaylist(); - - updatePlaylist(); + bindings.Name.BindValueChanged(n => name.Text = n, true); + bindings.EndDate.BindValueChanged(d => endDate.Date = d, true); } protected override void LoadComplete() @@ -262,14 +235,5 @@ namespace osu.Game.Screens.Multi.Lounge.Components base.LoadComplete(); this.FadeInFromZero(transition_duration); } - - private void updatePlaylist() - { - if (playlistBind.Count == 0) - return; - - // For now, only the first playlist item is supported - beatmap.Value = playlistBind.First().Beatmap; - } } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs index 042dd96b61..b0ce800d4b 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs @@ -21,8 +21,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components { private readonly FillFlowContainer levelRangeContainer; - public readonly Bindable Host = new Bindable(); - public readonly Bindable> Participants = new Bindable>(); + public readonly IBindable Host = new Bindable(); + public readonly IBindable> Participants = new Bindable>(); public ParticipantInfo(string rankPrefix = null) { diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index f290830334..08beace4ca 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; @@ -31,15 +30,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components public readonly IBindable Room = new Bindable(); private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; - private readonly Bindable nameBind = new Bindable(); - private readonly Bindable hostBind = new Bindable(); - private readonly Bindable statusBind = new Bindable(); - private readonly Bindable typeBind = new Bindable(); - private readonly Bindable maxParticipantsBind = new Bindable(); - private readonly Bindable> participantsBind = new Bindable>(); - private readonly IBindableCollection playlistBind = new BindableCollection(); - private readonly Bindable beatmap = new Bindable(); + private readonly RoomBindings bindings = new RoomBindings(); private OsuColour colours; private Box statusStrip; @@ -174,53 +166,27 @@ namespace osu.Game.Screens.Multi.Lounge.Components }, }; - playlistBind.ItemsAdded += _ => updatePlaylist(); - playlistBind.ItemsRemoved += _ => updatePlaylist(); + participantInfo.Host.BindTo(bindings.Host); + participantInfo.Participants.BindTo(bindings.Participants); + participantCount.Participants.BindTo(bindings.Participants); + participantCount.MaxParticipants.BindTo(bindings.MaxParticipants); + beatmapTypeInfo.Type.BindTo(bindings.Type); + background.Beatmap.BindTo(bindings.CurrentBeatmap); + beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); - statusBind.BindValueChanged(displayStatus); - participantsBind.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u))); - - nameBind.BindValueChanged(n => name.Text = n); - - participantInfo.Host.BindTo(hostBind); - participantInfo.Participants.BindTo(participantsBind); - - participantCount.Participants.BindTo(participantsBind); - participantCount.MaxParticipants.BindTo(maxParticipantsBind); - - beatmapTypeInfo.Type.BindTo(typeBind); - - background.Beatmap.BindTo(beatmap); - beatmapTypeInfo.Beatmap.BindTo(beatmap); + bindings.Status.BindValueChanged(displayStatus); + bindings.Participants.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u))); + bindings.Name.BindValueChanged(n => name.Text = n); Room.BindValueChanged(updateRoom, true); } - private Room lastRoom; - - private void updateRoom(Room newRoom) + private void updateRoom(Room room) { - if (lastRoom != null) - { - nameBind.UnbindFrom(lastRoom.Name); - hostBind.UnbindFrom(lastRoom.Host); - statusBind.UnbindFrom(lastRoom.Status); - typeBind.UnbindFrom(lastRoom.Type); - playlistBind.UnbindFrom(lastRoom.Playlist); - maxParticipantsBind.UnbindFrom(lastRoom.MaxParticipants); - participantsBind.UnbindFrom(lastRoom.Participants); - } + bindings.Room = room; - if (newRoom != null) + if (room != null) { - nameBind.BindTo(newRoom.Name); - hostBind.BindTo(newRoom.Host); - statusBind.BindTo(newRoom.Status); - typeBind.BindTo(newRoom.Type); - playlistBind.BindTo(newRoom.Playlist); - maxParticipantsBind.BindTo(newRoom.MaxParticipants); - participantsBind.BindTo(newRoom.Participants); - participantsFlow.FadeIn(transition_duration); participantCount.FadeIn(transition_duration); beatmapTypeInfo.FadeIn(transition_duration); @@ -237,17 +203,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components displayStatus(new RoomStatusNoneSelected()); } - - lastRoom = newRoom; - } - - private void updatePlaylist() - { - if (playlistBind.Count == 0) - return; - - // For now, only the first playlist item is supported - beatmap.Value = playlistBind.First().Beatmap; } protected override void UpdateAfterChildren() diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 3f4f137413..f306ee698f 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -27,9 +27,9 @@ namespace osu.Game.Screens.Multi.Match.Components { public const float HEIGHT = 200; - public readonly Bindable Beatmap = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); public readonly IBindable Type = new Bindable(); - public readonly Bindable> Mods = new Bindable>(); + public readonly IBindable> Mods = new Bindable>(); private readonly Box tabStrip; @@ -116,11 +116,11 @@ namespace osu.Game.Screens.Multi.Match.Components beatmapTypeInfo.Beatmap.BindTo(Beatmap); beatmapTypeInfo.Type.BindTo(Type); - modDisplay.Current.BindTo(Mods); + background.Beatmap.BindTo(Beatmap); + Mods.BindValueChanged(m => modDisplay.Current.Value = m, true); beatmapButton.Action = () => OnRequestSelectBeatmap?.Invoke(); - background.Beatmap.BindTo(Beatmap); } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index de02899a01..b849cae5d0 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -26,11 +26,11 @@ namespace osu.Game.Screens.Multi.Match.Components private OsuColour colours; - public readonly Bindable Name = new Bindable(); - public readonly Bindable Availability = new Bindable(); - public readonly Bindable Status = new Bindable(); - public readonly Bindable Beatmap = new Bindable(); - public readonly Bindable EndDate = new Bindable(); + public readonly IBindable Name = new Bindable(); + public readonly IBindable Availability = new Bindable(); + public readonly IBindable Status = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); + public readonly IBindable EndDate = new Bindable(); public Info(Room room) { diff --git a/osu.Game/Screens/Multi/Match/Components/Participants.cs b/osu.Game/Screens/Multi/Match/Components/Participants.cs index 92732dc045..4f18fc9f4c 100644 --- a/osu.Game/Screens/Multi/Match/Components/Participants.cs +++ b/osu.Game/Screens/Multi/Match/Components/Participants.cs @@ -15,14 +15,8 @@ namespace osu.Game.Screens.Multi.Match.Components { public class Participants : CompositeDrawable { - public readonly Bindable> Users = new Bindable>(); - public readonly Bindable MaxParticipants = new Bindable(); - - public new MarginPadding Padding - { - get => base.Padding; - set => base.Padding = value; - } + public readonly IBindable> Users = new Bindable>(); + public readonly IBindable MaxParticipants = new Bindable(); public Participants() { diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index bab44d62b2..65e1f068a8 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -4,7 +4,6 @@ using System; using Humanizer; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -24,12 +23,7 @@ namespace osu.Game.Screens.Multi.Match.Components private const float transition_duration = 350; private const float field_padding = 45; - private readonly Bindable nameBind = new Bindable(); - private readonly Bindable availabilityBind = new Bindable(); - private readonly Bindable typeBind = new Bindable(); - private readonly Bindable maxParticipantsBind = new Bindable(); - private readonly IBindableCollection playlistBind = new BindableCollection(); - private readonly Bindable durationBind = new Bindable(); + private readonly RoomBindings bindings = new RoomBindings(); private readonly Container content; @@ -51,6 +45,8 @@ namespace osu.Game.Screens.Multi.Match.Components { this.room = room; + bindings.Room = room; + Masking = true; Child = content = new Container @@ -189,11 +185,11 @@ namespace osu.Game.Screens.Multi.Match.Components TypePicker.Current.ValueChanged += t => typeLabel.Text = t.Name; - nameBind.ValueChanged += n => NameField.Text = n; - availabilityBind.ValueChanged += a => AvailabilityPicker.Current.Value = a; - typeBind.ValueChanged += t => TypePicker.Current.Value = t; - maxParticipantsBind.ValueChanged += m => MaxParticipantsField.Text = m?.ToString(); - durationBind.ValueChanged += d => DurationField.Current.Value = d; + bindings.Name.BindValueChanged(n => NameField.Text = n, true); + bindings.Availability.BindValueChanged(a => AvailabilityPicker.Current.Value = a, true); + bindings.Type.BindValueChanged(t => TypePicker.Current.Value = t, true); + bindings.MaxParticipants.BindValueChanged(m => MaxParticipantsField.Text = m?.ToString(), true); + bindings.Duration.BindValueChanged(d => DurationField.Current.Value = d, true); } [BackgroundDependencyLoader] @@ -201,13 +197,6 @@ namespace osu.Game.Screens.Multi.Match.Components { typeLabel.Colour = colours.Yellow; - nameBind.BindTo(room.Name); - playlistBind.BindTo(room.Playlist); - availabilityBind.BindTo(room.Availability); - typeBind.BindTo(room.Type); - maxParticipantsBind.BindTo(room.MaxParticipants); - durationBind.BindTo(room.Duration); - MaxParticipantsField.ReadOnly = true; PasswordField.ReadOnly = true; AvailabilityPicker.ReadOnly.Value = true; @@ -222,19 +211,10 @@ namespace osu.Game.Screens.Multi.Match.Components ApplyButton.Enabled.Value = hasValidSettings; } - private bool hasValidSettings => NameField.Text.Length > 0 && playlistBind.Count > 0; + private bool hasValidSettings => NameField.Text.Length > 0 && bindings.Playlist.Count > 0; protected override void PopIn() { - // reapply the rooms values if the overlay was completely closed - if (content.Y == -1) - { - nameBind.TriggerChange(); - availabilityBind.TriggerChange(); - typeBind.TriggerChange(); - maxParticipantsBind.TriggerChange(); - } - content.MoveToY(0, transition_duration, Easing.OutQuint); } @@ -245,16 +225,16 @@ namespace osu.Game.Screens.Multi.Match.Components private void apply() { - nameBind.Value = NameField.Text; - availabilityBind.Value = AvailabilityPicker.Current.Value; - typeBind.Value = TypePicker.Current.Value; + bindings.Name.Value = NameField.Text; + bindings.Availability.Value = AvailabilityPicker.Current.Value; + bindings.Type.Value = TypePicker.Current.Value; if (int.TryParse(MaxParticipantsField.Text, out int max)) - maxParticipantsBind.Value = max; + bindings.MaxParticipants.Value = max; else - maxParticipantsBind.Value = null; + bindings.MaxParticipants.Value = null; - durationBind.Value = DurationField.Current.Value; + bindings.Duration.Value = DurationField.Current.Value; manager?.CreateRoom(room); } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index dfedf6d7a1..98a980afb2 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -5,39 +5,28 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Play; using osu.Game.Screens.Play; using osu.Game.Screens.Select; -using osu.Game.Users; namespace osu.Game.Screens.Multi.Match { public class MatchScreen : MultiplayerScreen { - private readonly Bindable nameBind = new Bindable(); - private readonly Bindable statusBind = new Bindable(); - private readonly Bindable availabilityBind = new Bindable(); - private readonly Bindable typeBind = new Bindable(); - private readonly Bindable maxParticipantsBind = new Bindable(); - private readonly Bindable> participantsBind = new Bindable>(); - private readonly BindableCollection playlistBind = new BindableCollection(); - private readonly Bindable endDateBind = new Bindable(); - public override bool AllowBeatmapRulesetChange => false; - public override string Title => room.Name.Value; - public override string ShortTitle => "room"; - private readonly Components.Header header; - private readonly Info info; + private readonly RoomBindings bindings = new RoomBindings(); + private readonly MatchLeaderboard leaderboard; private readonly Action pushGameplayScreen; @@ -58,14 +47,10 @@ namespace osu.Game.Screens.Multi.Match this.room = room; this.pushGameplayScreen = pushGameplayScreen; - nameBind.BindTo(room.Name); - statusBind.BindTo(room.Status); - availabilityBind.BindTo(room.Availability); - typeBind.BindTo(room.Type); - participantsBind.BindTo(room.Participants); - maxParticipantsBind.BindTo(room.MaxParticipants); - endDateBind.BindTo(room.EndDate); + bindings.Room = room; + Info info; + Components.Header header; RoomSettingsOverlay settings; Children = new Drawable[] @@ -113,7 +98,6 @@ namespace osu.Game.Screens.Multi.Match }; header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect { Selected = addPlaylistItem }); - header.Tabs.Current.ValueChanged += t => { if (t is SettingsMatchPage) @@ -122,55 +106,55 @@ namespace osu.Game.Screens.Multi.Match settings.Hide(); }; - info.Name.BindTo(nameBind); - info.Status.BindTo(statusBind); - info.Availability.BindTo(availabilityBind); - info.EndDate.BindTo(endDateBind); - - header.Type.BindTo(typeBind); - - playlistBind.ItemsAdded += _ => setFromPlaylist(); - playlistBind.ItemsRemoved += _ => setFromPlaylist(); + info.Name.BindTo(bindings.Name); + info.Status.BindTo(bindings.Status); + info.Availability.BindTo(bindings.Availability); + info.EndDate.BindTo(bindings.EndDate); + info.Beatmap.BindTo(bindings.CurrentBeatmap); + header.Type.BindTo(bindings.Type); + header.Beatmap.BindTo(bindings.CurrentBeatmap); + header.Mods.BindTo(bindings.CurrentMods); } protected override void LoadComplete() { base.LoadComplete(); - playlistBind.BindTo(room.Playlist); + bindings.CurrentBeatmap.BindValueChanged(setBeatmap, true); + bindings.CurrentMods.BindValueChanged(setMods, true); + bindings.CurrentRuleset.BindValueChanged(setRuleset, true); + } + + private void setBeatmap(BeatmapInfo beatmap) + { + // Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info + var localBeatmap = beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID); + + game.ForcefullySetBeatmap(beatmapManager.GetWorkingBeatmap(localBeatmap)); + } + + private void setMods(IEnumerable mods) + { + Beatmap.Value.Mods.Value = mods.ToArray(); + } + + private void setRuleset(RulesetInfo ruleset) + { + if (ruleset == null) + return; + + game.ForcefullySetRuleset(ruleset); } private void addPlaylistItem(PlaylistItem item) { - playlistBind.Clear(); - playlistBind.Add(item); - } - - private void setFromPlaylist() - { - if (playlistBind.Count == 0) - return; - - // For now, only the first playlist item is supported - var item = playlistBind.First(); - - header.Beatmap.Value = item.Beatmap; - header.Mods.Value = item.RequiredMods; - info.Beatmap.Value = item.Beatmap; - - // Todo: item.Beatmap can be null here... - var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.BeatmapID) ?? item.Beatmap; - - var newBeatmap = beatmapManager.GetWorkingBeatmap(localBeatmap); - newBeatmap.Mods.Value = item.RequiredMods.ToArray(); - - game.ForcefullySetBeatmap(newBeatmap); - game.ForcefullySetRuleset(item.Ruleset); + bindings.Playlist.Clear(); + bindings.Playlist.Add(item); } private void onStart() { - switch (typeBind.Value) + switch (bindings.Type.Value) { default: case GameTypeTimeshift _: diff --git a/osu.Game/Screens/Multi/RoomBindings.cs b/osu.Game/Screens/Multi/RoomBindings.cs new file mode 100644 index 0000000000..b5854bf957 --- /dev/null +++ b/osu.Game/Screens/Multi/RoomBindings.cs @@ -0,0 +1,101 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Configuration; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Users; + +namespace osu.Game.Screens.Multi +{ + /// + /// Helper class which binds to values from a . + /// + public class RoomBindings + { + public RoomBindings() + { + Playlist.ItemsAdded += _ => updatePlaylist(); + Playlist.ItemsRemoved += _ => updatePlaylist(); + } + + private Room room; + + /// + /// The to bind to. + /// + public Room Room + { + get => room; + set + { + if (room == value) + return; + + if (room != null) + { + Name.UnbindFrom(room.Name); + Host.UnbindFrom(room.Host); + Status.UnbindFrom(room.Status); + Type.UnbindFrom(room.Type); + Playlist.UnbindFrom(room.Playlist); + MaxParticipants.UnbindFrom(room.MaxParticipants); + Participants.UnbindFrom(room.Participants); + Availability.UnbindFrom(room.Availability); + Duration.UnbindFrom(room.Duration); + } + + room = value; + + if (room != null) + { + Name.BindTo(room.Name); + Host.BindTo(room.Host); + Status.BindTo(room.Status); + Type.BindTo(room.Type); + Playlist.BindTo(room.Playlist); + MaxParticipants.BindTo(room.MaxParticipants); + Participants.BindTo(room.Participants); + Availability.BindTo(room.Availability); + Duration.BindTo(room.Duration); + } + } + } + + private void updatePlaylist() + { + // Todo: We only ever have one playlist item for now. In the future, this will be user-settable + + var playlistItem = Playlist.FirstOrDefault(); + + currentBeatmap.Value = playlistItem?.Beatmap; + currentMods.Value = playlistItem?.RequiredMods ?? Enumerable.Empty(); + currentRuleset.Value = playlistItem?.Ruleset; + } + + public readonly Bindable Name = new Bindable(); + public readonly Bindable Host = new Bindable(); + public readonly Bindable Status = new Bindable(); + public readonly Bindable Type = new Bindable(); + public readonly BindableCollection Playlist = new BindableCollection(); + public readonly Bindable> Participants = new Bindable>(); + public readonly Bindable MaxParticipants = new Bindable(); + public readonly Bindable EndDate = new Bindable(); + public readonly Bindable Availability = new Bindable(); + public readonly Bindable Duration = new Bindable(); + + private readonly Bindable currentBeatmap = new Bindable(); + public IBindable CurrentBeatmap => currentBeatmap; + + private readonly Bindable> currentMods = new Bindable>(); + public IBindable> CurrentMods => currentMods; + + private readonly Bindable currentRuleset = new Bindable(); + public IBindable CurrentRuleset = new Bindable(); + } +} From c06cf5d379cf0ca409f5ebb45051de69a366c064 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 14:08:00 +0900 Subject: [PATCH 107/220] Decouple match info from match screen --- .../Screens/Multi/Match/Components/Info.cs | 28 ++++++++----------- osu.Game/Screens/Multi/Match/MatchScreen.cs | 8 +----- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index b849cae5d0..ca1ca5f40f 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -3,12 +3,10 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.Multiplayer; @@ -26,11 +24,7 @@ namespace osu.Game.Screens.Multi.Match.Components private OsuColour colours; - public readonly IBindable Name = new Bindable(); - public readonly IBindable Availability = new Bindable(); - public readonly IBindable Status = new Bindable(); - public readonly IBindable Beatmap = new Bindable(); - public readonly IBindable EndDate = new Bindable(); + private readonly RoomBindings bindings = new RoomBindings(); public Info(Room room) { @@ -99,13 +93,15 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - viewBeatmapButton.Beatmap.BindTo(Beatmap); - readyButton.Beatmap.BindTo(Beatmap); + viewBeatmapButton.Beatmap.BindTo(bindings.CurrentBeatmap); + readyButton.Beatmap.BindTo(bindings.CurrentBeatmap); - Availability.BindValueChanged(_ => updateAvailabilityStatus()); - Status.BindValueChanged(_ => updateAvailabilityStatus()); - Name.BindValueChanged(n => name.Text = n); - EndDate.BindValueChanged(d => endDate.Date = d); + bindings.Availability.BindValueChanged(_ => updateAvailabilityStatus()); + bindings.Status.BindValueChanged(_ => updateAvailabilityStatus()); + bindings.Name.BindValueChanged(n => name.Text = n); + bindings.EndDate.BindValueChanged(d => endDate.Date = d); + + bindings.Room = room; } [BackgroundDependencyLoader] @@ -126,10 +122,10 @@ namespace osu.Game.Screens.Multi.Match.Components if (!IsLoaded) return; - if (Status.Value != null) + if (bindings.Status.Value != null) { - availabilityStatus.FadeColour(Status.Value.GetAppropriateColour(colours), 100); - availabilityStatus.Text = $"{Availability.Value.GetDescription()}, {Status.Value.Message}"; + availabilityStatus.FadeColour(bindings.Status.Value.GetAppropriateColour(colours), 100); + availabilityStatus.Text = $"{bindings.Availability.Value.GetDescription()}, {bindings.Status.Value.Message}"; } } } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 98a980afb2..513b49713a 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -49,7 +49,6 @@ namespace osu.Game.Screens.Multi.Match bindings.Room = room; - Info info; Components.Header header; RoomSettingsOverlay settings; @@ -61,7 +60,7 @@ namespace osu.Game.Screens.Multi.Match Content = new[] { new Drawable[] { header = new Components.Header(room) { Depth = -1 } }, - new Drawable[] { info = new Info(room) { OnStart = onStart } }, + new Drawable[] { new Info(room) { OnStart = onStart } }, new Drawable[] { new GridContainer @@ -106,11 +105,6 @@ namespace osu.Game.Screens.Multi.Match settings.Hide(); }; - info.Name.BindTo(bindings.Name); - info.Status.BindTo(bindings.Status); - info.Availability.BindTo(bindings.Availability); - info.EndDate.BindTo(bindings.EndDate); - info.Beatmap.BindTo(bindings.CurrentBeatmap); header.Type.BindTo(bindings.Type); header.Beatmap.BindTo(bindings.CurrentBeatmap); header.Mods.BindTo(bindings.CurrentMods); From 21cfe5a3e67b253b1e05175ecf6160c9381801cf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 14:12:27 +0900 Subject: [PATCH 108/220] Decouple header from matchscreen --- osu.Game.Tests/Visual/TestCaseMatchHeader.cs | 45 +++++++++---------- .../Screens/Multi/Match/Components/Header.cs | 18 +++----- osu.Game/Screens/Multi/Match/MatchScreen.cs | 4 -- 3 files changed, 27 insertions(+), 40 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatchHeader.cs b/osu.Game.Tests/Visual/TestCaseMatchHeader.cs index 8ff16a20b9..ac964e22a6 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchHeader.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchHeader.cs @@ -3,10 +3,8 @@ using System; using System.Collections.Generic; -using osu.Framework.Configuration; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Multi.Match.Components; @@ -20,37 +18,34 @@ namespace osu.Game.Tests.Visual typeof(Header) }; - private readonly Bindable beatmap = new Bindable(); - private readonly Bindable type = new Bindable(); - private readonly Bindable> mods = new Bindable>(); - public TestCaseMatchHeader() { - var header = new Header(new Room()); + var room = new Room(); - header.Beatmap.BindTo(beatmap); - header.Type.BindTo(type); - header.Mods.BindTo(mods); + var header = new Header(room); - beatmap.Value = new BeatmapInfo + room.Playlist.Add(new PlaylistItem { - Metadata = new BeatmapMetadata + Beatmap = new BeatmapInfo { - Title = "Title", - Artist = "Artist", - AuthorString = "Author", + Metadata = new BeatmapMetadata + { + Title = "Title", + Artist = "Artist", + AuthorString = "Author", + }, + Version = "Version", + Ruleset = new OsuRuleset().RulesetInfo }, - Version = "Version", - Ruleset = new OsuRuleset().RulesetInfo - }; + RequiredMods = + { + new OsuModDoubleTime(), + new OsuModNoFail(), + new OsuModRelax(), + } + }); - type.Value = new GameTypeTimeshift(); - mods.Value = new Mod[] - { - new OsuModDoubleTime(), - new OsuModNoFail(), - new OsuModRelax(), - }; + room.Type.Value = new GameTypeTimeshift(); Child = header; } diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index f306ee698f..b2d39151c1 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; @@ -10,12 +9,10 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; -using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Play.HUD; using osuTK; @@ -27,9 +24,7 @@ namespace osu.Game.Screens.Multi.Match.Components { public const float HEIGHT = 200; - public readonly IBindable Beatmap = new Bindable(); - public readonly IBindable Type = new Bindable(); - public readonly IBindable> Mods = new Bindable>(); + private readonly RoomBindings bindings = new RoomBindings(); private readonly Box tabStrip; @@ -42,6 +37,8 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.X; Height = HEIGHT; + bindings.Room = room; + BeatmapTypeInfo beatmapTypeInfo; BeatmapSelectButton beatmapButton; UpdateableBeatmapBackgroundSprite background; @@ -114,13 +111,12 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - beatmapTypeInfo.Beatmap.BindTo(Beatmap); - beatmapTypeInfo.Type.BindTo(Type); - background.Beatmap.BindTo(Beatmap); - Mods.BindValueChanged(m => modDisplay.Current.Value = m, true); + beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); + beatmapTypeInfo.Type.BindTo(bindings.Type); + background.Beatmap.BindTo(bindings.CurrentBeatmap); + bindings.CurrentMods.BindValueChanged(m => modDisplay.Current.Value = m, true); beatmapButton.Action = () => OnRequestSelectBeatmap?.Invoke(); - } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 513b49713a..9a5950417b 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -104,10 +104,6 @@ namespace osu.Game.Screens.Multi.Match else settings.Hide(); }; - - header.Type.BindTo(bindings.Type); - header.Beatmap.BindTo(bindings.CurrentBeatmap); - header.Mods.BindTo(bindings.CurrentMods); } protected override void LoadComplete() From 7191233be8ed55d5a5a7520951bf067559a8f38f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 14:14:14 +0900 Subject: [PATCH 109/220] Allow roommanager to be null --- osu.Game/Screens/Multi/Lounge/LoungeScreen.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index a6d4d845e0..8be7afad8b 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -22,7 +22,7 @@ namespace osu.Game.Screens.Multi.Lounge private readonly RoomsContainer rooms; private readonly Action pushGameplayScreen; - [Resolved] + [Resolved(CanBeNull = true)] private RoomManager roomManager { get; set; } public override string Title => "Lounge"; @@ -80,7 +80,8 @@ namespace osu.Game.Screens.Multi.Lounge [BackgroundDependencyLoader] private void load() { - roomManager.OpenRequested += Open; + if (roomManager != null) + roomManager.OpenRequested += Open; } protected override void UpdateAfterChildren() @@ -130,7 +131,7 @@ namespace osu.Game.Screens.Multi.Lounge private void filterRooms() { rooms.Filter(Filter.CreateCriteria()); - roomManager.Filter(Filter.CreateCriteria()); + roomManager?.Filter(Filter.CreateCriteria()); } public void Open(Room room) From dbd391825aced3fb7ac510dcb1bcbdc50a778232 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 14:29:27 +0900 Subject: [PATCH 110/220] Rework+fix TestCaseMultiHeader --- osu.Game.Tests/Visual/TestCaseMultiHeader.cs | 30 +++++++++++++++----- osu.Game/Screens/Multi/Header.cs | 3 +- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMultiHeader.cs b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs index deb098e97d..2005c707b1 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiHeader.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs @@ -3,8 +3,8 @@ using NUnit.Framework; using osu.Framework.Graphics; +using osu.Game.Screens; using osu.Game.Screens.Multi; -using osu.Game.Screens.Multi.Lounge; namespace osu.Game.Tests.Visual { @@ -13,15 +13,31 @@ namespace osu.Game.Tests.Visual { public TestCaseMultiHeader() { - LoungeScreen loungeScreen; + int index = 0; + + OsuScreen currentScreen = new TestMultiplayerScreen(index); + Children = new Drawable[] { - loungeScreen = new LoungeScreen(null) - { - Padding = new MarginPadding { Top = Header.HEIGHT }, - }, - new Header(loungeScreen), + currentScreen, + new Header(currentScreen) }; + + AddStep("push multi screen", () => currentScreen.Push(currentScreen = new TestMultiplayerScreen(++index))); + } + + private class TestMultiplayerScreen : OsuScreen, IMultiplayerScreen + { + private readonly int index; + + public string ShortTitle => $"Screen {index}"; + + public TestMultiplayerScreen(int index) + { + this.index = index; + } + + public override string ToString() => ShortTitle; } } } diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 570db11d50..849be44f4f 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -103,7 +103,8 @@ namespace osu.Game.Screens.Multi private class HeaderBreadcrumbControl : ScreenBreadcrumbControl { - public HeaderBreadcrumbControl(Screen initialScreen) : base(initialScreen) + public HeaderBreadcrumbControl(Screen initialScreen) + : base(initialScreen) { } From 09d7dc73dc043240e33c4136bafd55353fa9420e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 14:38:46 +0900 Subject: [PATCH 111/220] Allow channel manager and osugame to be null --- osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs | 4 ++-- osu.Game/Screens/Multi/Match/MatchScreen.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs b/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs index ecb7b86fb4..0d7221754f 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Multi.Match.Components { private readonly Room room; - [Resolved] + [Resolved(CanBeNull = true)] private ChannelManager channelManager { get; set; } public MatchChatDisplay(Room room) @@ -30,7 +30,7 @@ namespace osu.Game.Screens.Multi.Match.Components private void updateChannel() { if (room.RoomID.Value != null) - Channel.Value = channelManager.JoinChannel(new Channel { Id = room.ChannelId, Type = ChannelType.Multiplayer, Name = $"#mp_{room.RoomID}" }); + Channel.Value = channelManager?.JoinChannel(new Channel { Id = room.ChannelId, Type = ChannelType.Multiplayer, Name = $"#mp_{room.RoomID}" }); } } } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 9a5950417b..72803c20a0 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Multi.Match [Resolved] private BeatmapManager beatmapManager { get; set; } - [Resolved] + [Resolved(CanBeNull = true)] private OsuGame game { get; set; } [Resolved(CanBeNull = true)] @@ -120,7 +120,7 @@ namespace osu.Game.Screens.Multi.Match // Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info var localBeatmap = beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID); - game.ForcefullySetBeatmap(beatmapManager.GetWorkingBeatmap(localBeatmap)); + game?.ForcefullySetBeatmap(beatmapManager.GetWorkingBeatmap(localBeatmap)); } private void setMods(IEnumerable mods) @@ -133,7 +133,7 @@ namespace osu.Game.Screens.Multi.Match if (ruleset == null) return; - game.ForcefullySetRuleset(ruleset); + game?.ForcefullySetRuleset(ruleset); } private void addPlaylistItem(PlaylistItem item) From b82bb0ea281f2851c39b960f3affc436563267d0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 14:40:10 +0900 Subject: [PATCH 112/220] Mate RoomSettingsOverlay fill height --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 72803c20a0..927b786ab5 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -88,11 +88,7 @@ namespace osu.Game.Screens.Multi.Match { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Components.Header.HEIGHT }, - Child = settings = new RoomSettingsOverlay(room) - { - RelativeSizeAxes = Axes.Both, - Height = 0.9f, - }, + Child = settings = new RoomSettingsOverlay(room) { RelativeSizeAxes = Axes.Both }, }, }; From 34fc740e1f72e6ec4b8f5865d0e2f008d2973a02 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 14:48:15 +0900 Subject: [PATCH 113/220] Implement testcase for room settings --- .../Visual/TestCaseMatchSettingsOverlay.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs new file mode 100644 index 0000000000..dd5d242f56 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Match.Components; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseMatchSettingsOverlay : OsuTestCase + { + public TestCaseMatchSettingsOverlay() + { + Child = new RoomSettingsOverlay(new Room()) + { + RelativeSizeAxes = Axes.Both, + State = Visibility.Visible + }; + } + } +} From 6afd2f72634aee31a1583e012ef7cf2f69b0e213 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 15:00:35 +0900 Subject: [PATCH 114/220] Adjust styling of disabled settings --- .../Visual/TestCaseMatchSettingsOverlay.cs | 7 +++++++ .../Multi/Components/DisableableTabControl.cs | 15 ++++----------- .../Multi/Match/Components/RoomSettingsOverlay.cs | 9 +++++++-- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index dd5d242f56..fede2f509f 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.Multiplayer; @@ -10,6 +12,11 @@ namespace osu.Game.Tests.Visual { public class TestCaseMatchSettingsOverlay : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(RoomSettingsOverlay) + }; + public TestCaseMatchSettingsOverlay() { Child = new RoomSettingsOverlay(new Room()) diff --git a/osu.Game/Screens/Multi/Components/DisableableTabControl.cs b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs index fdc2fd578d..dc765832db 100644 --- a/osu.Game/Screens/Multi/Components/DisableableTabControl.cs +++ b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs @@ -4,39 +4,32 @@ using osu.Framework.Configuration; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; -using osuTK.Graphics; namespace osu.Game.Screens.Multi.Components { public abstract class DisableableTabControl : TabControl { - public readonly BindableBool ReadOnly = new BindableBool(); + public readonly BindableBool Enabled = new BindableBool(); protected override void AddTabItem(TabItem tab, bool addToDropdown = true) { if (tab is DisableableTabItem disableable) - disableable.ReadOnly.BindTo(ReadOnly); + disableable.Enabled.BindTo(Enabled); base.AddTabItem(tab, addToDropdown); } protected abstract class DisableableTabItem : TabItem { - public readonly BindableBool ReadOnly = new BindableBool(); + public readonly BindableBool Enabled = new BindableBool(); protected DisableableTabItem(T value) : base(value) { - ReadOnly.BindValueChanged(updateReadOnly); - } - - private void updateReadOnly(bool readOnly) - { - Colour = readOnly ? Color4.Gray : Color4.White; } protected override bool OnClick(ClickEvent e) { - if (ReadOnly) + if (!Enabled) return true; return base.OnClick(e); } diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index 65e1f068a8..db29722025 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -22,6 +22,7 @@ namespace osu.Game.Screens.Multi.Match.Components { private const float transition_duration = 350; private const float field_padding = 45; + private const float disabled_alpha = 0.2f; private readonly RoomBindings bindings = new RoomBindings(); @@ -82,10 +83,12 @@ namespace osu.Game.Screens.Multi.Match.Components }, new Section("ROOM VISIBILITY") { + Alpha = disabled_alpha, Child = AvailabilityPicker = new RoomAvailabilityPicker(), }, new Section("GAME TYPE") { + Alpha = disabled_alpha, Child = new FillFlowContainer { AutoSizeAxes = Axes.Y, @@ -116,6 +119,7 @@ namespace osu.Game.Screens.Multi.Match.Components { new Section("MAX PARTICIPANTS") { + Alpha = disabled_alpha, Child = MaxParticipantsField = new SettingsNumberTextBox { RelativeSizeAxes = Axes.X, @@ -146,6 +150,7 @@ namespace osu.Game.Screens.Multi.Match.Components }, new Section("PASSWORD (OPTIONAL)") { + Alpha = disabled_alpha, Child = PasswordField = new SettingsPasswordTextBox { RelativeSizeAxes = Axes.X, @@ -199,8 +204,8 @@ namespace osu.Game.Screens.Multi.Match.Components MaxParticipantsField.ReadOnly = true; PasswordField.ReadOnly = true; - AvailabilityPicker.ReadOnly.Value = true; - TypePicker.ReadOnly.Value = true; + AvailabilityPicker.Enabled.Value = false; + TypePicker.Enabled.Value = false; ApplyButton.Enabled.Value = false; } From 3570c35d7fd7495ff52d8e502a98a1e6e247a15f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 15:17:35 +0900 Subject: [PATCH 115/220] Make RoomScore derive ScoreInfo --- osu.Game/Scoring/ScoreInfo.cs | 5 +++-- .../Multi/Match/Components/MatchLeaderboard.cs | 14 +------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index a689590819..8ffade1e2b 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -98,8 +98,9 @@ namespace osu.Game.Scoring } } - [JsonIgnore] - public User User; + [NotMapped] + [JsonProperty("user")] + public User User { get; set; } [JsonIgnore] [Column("User")] diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 4b09349be5..2fbeea4377 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -102,20 +102,8 @@ namespace osu.Game.Screens.Multi.Match.Components Overall } - public class RoomScore + public class RoomScore : ScoreInfo { - [JsonProperty("user")] - public User User { get; set; } - - [JsonProperty("accuracy")] - public double Accuracy { get; set; } - - [JsonProperty("total_score")] - public int TotalScore { get; set; } - - [JsonProperty("pp")] - public double? PP { get; set; } - [JsonProperty("attempts")] public int TotalAttempts { get; set; } From ac0e6f8d42eface1fead880b79b40cd8db1833ff Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 15:35:22 +0900 Subject: [PATCH 116/220] Fix post-merge issues --- .../Match/Components/MatchLeaderboard.cs | 23 ++++--------- .../Leaderboards/BeatmapLeaderboardScore.cs | 34 ------------------- 2 files changed, 6 insertions(+), 51 deletions(-) delete mode 100644 osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScore.cs diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 2fbeea4377..d6c7c28840 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -3,16 +3,13 @@ using System; using System.Collections.Generic; -using System.Linq; using Newtonsoft.Json; using osu.Framework.Allocation; using osu.Game.Graphics; using osu.Game.Online.API; using osu.Game.Online.Leaderboards; using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets.Mods; using osu.Game.Scoring; -using osu.Game.Users; namespace osu.Game.Screens.Multi.Match.Components { @@ -53,7 +50,7 @@ namespace osu.Game.Screens.Multi.Match.Components return req; } - protected override LeaderboardScore CreateScoreVisualiser(RoomScore model, int index) => new MatchLeaderboardScore(model, index); + protected override LeaderboardScore CreateDrawableScore(RoomScore model, int index) => new MatchLeaderboardScore(model, index); private class GetRoomScoresRequest : APIRequest> { @@ -68,7 +65,7 @@ namespace osu.Game.Screens.Multi.Match.Components } } - public class MatchLeaderboardScore : LeaderboardScore + public class MatchLeaderboardScore : LeaderboardScore { public MatchLeaderboardScore(RoomScore score, int rank) : base(score, rank) @@ -81,20 +78,12 @@ namespace osu.Game.Screens.Multi.Match.Components RankContainer.Alpha = 0; } - protected override User GetUser(RoomScore model) => model.User; - - protected override IEnumerable GetMods(RoomScore model) => Enumerable.Empty(); // Not implemented yet - - protected override IEnumerable<(FontAwesome icon, string value, string name)> GetStatistics(RoomScore model) => new[] + protected override IEnumerable GetStatistics(ScoreInfo model) => new[] { - (FontAwesome.fa_crosshairs, string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy), "Accuracy"), - (FontAwesome.fa_refresh, model.TotalAttempts.ToString(), "Total Attempts"), - (FontAwesome.fa_check, model.CompletedAttempts.ToString(), "Completed Beatmaps"), + new LeaderboardScoreStatistic(FontAwesome.fa_crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)), + new LeaderboardScoreStatistic(FontAwesome.fa_refresh, "Total Attempts", ((RoomScore)model).TotalAttempts.ToString()), + new LeaderboardScoreStatistic(FontAwesome.fa_check, "Completed Beatmaps", ((RoomScore)model).CompletedAttempts.ToString()), }; - - protected override int GetTotalScore(RoomScore model) => model.TotalScore; - - protected override ScoreRank GetRank(RoomScore model) => ScoreRank.S; } public enum MatchLeaderboardScope diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScore.cs deleted file mode 100644 index 098fff4052..0000000000 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScore.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.Collections.Generic; -using osu.Game.Graphics; -using osu.Game.Online.Leaderboards; -using osu.Game.Rulesets.Mods; -using osu.Game.Scoring; -using osu.Game.Users; - -namespace osu.Game.Screens.Select.Leaderboards -{ - public class BeatmapLeaderboardScore : LeaderboardScore - { - public BeatmapLeaderboardScore(ScoreInfo score, int rank) - : base(score, rank) - { - } - - protected override User GetUser(ScoreInfo model) => model.User; - - protected override IEnumerable GetMods(ScoreInfo model) => model.Mods; - - protected override IEnumerable<(FontAwesome icon, string value, string name)> GetStatistics(ScoreInfo model) => new[] - { - (FontAwesome.fa_link, model.MaxCombo.ToString(), "Max Combo"), - (FontAwesome.fa_crosshairs, string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy), "Accuracy") - }; - - protected override int GetTotalScore(ScoreInfo model) => model.TotalScore; - - protected override ScoreRank GetRank(ScoreInfo model) => model.Rank; - } -} From b9ec179713b1972810055caf5b3b894e1b649964 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 15:45:16 +0900 Subject: [PATCH 117/220] Split out more requests + responses --- osu.Game.Tests/Visual/TestCaseMultiResults.cs | 5 ++- .../API/Requests/CreateRoomScoreRequest.cs | 2 +- .../API/Requests/GetRoomScoresRequest.cs | 20 ++++++++++ .../Requests/Responses/APIRoomScoreInfo.cs | 17 +++++++++ .../{APIRoomScore.cs => APIScoreToken.cs} | 2 +- .../Match/Components/MatchLeaderboard.cs | 38 +++++-------------- .../Ranking/Pages/RoomRankingResultsPage.cs | 5 ++- 7 files changed, 54 insertions(+), 35 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetRoomScoresRequest.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs rename osu.Game/Online/API/Requests/Responses/{APIRoomScore.cs => APIScoreToken.cs} (90%) diff --git a/osu.Game.Tests/Visual/TestCaseMultiResults.cs b/osu.Game.Tests/Visual/TestCaseMultiResults.cs index 988ba0efdc..deb5d88ad2 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiResults.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiResults.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.API; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Multiplayer; using osu.Game.Scoring; using osu.Game.Screens.Multi.Match.Components; @@ -101,7 +102,7 @@ namespace osu.Game.Tests.Visual { } - protected override APIRequest FetchScores(Action> scoresCallback) + protected override APIRequest FetchScores(Action> scoresCallback) { var scores = Enumerable.Range(0, 50).Select(createRoomScore).ToArray(); @@ -111,7 +112,7 @@ namespace osu.Game.Tests.Visual return null; } - private RoomScore createRoomScore(int id) => new RoomScore + private APIRoomScoreInfo createRoomScore(int id) => new APIRoomScoreInfo { User = new User { Id = id, Username = $"User {id}" }, Accuracy = 0.98, diff --git a/osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs b/osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs index 99640f435e..0e99b53ec0 100644 --- a/osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs +++ b/osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs @@ -7,7 +7,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class CreateRoomScoreRequest : APIRequest + public class CreateRoomScoreRequest : APIRequest { private readonly int roomId; private readonly int playlistItemId; diff --git a/osu.Game/Online/API/Requests/GetRoomScoresRequest.cs b/osu.Game/Online/API/Requests/GetRoomScoresRequest.cs new file mode 100644 index 0000000000..1699694878 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetRoomScoresRequest.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetRoomScoresRequest : APIRequest> + { + private readonly int roomId; + + public GetRoomScoresRequest(int roomId) + { + this.roomId = roomId; + } + + protected override string Target => $@"rooms/{roomId}/leaderboard"; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs new file mode 100644 index 0000000000..2394db3825 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; +using osu.Game.Scoring; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIRoomScoreInfo : ScoreInfo + { + [JsonProperty("attempts")] + public int TotalAttempts { get; set; } + + [JsonProperty("completed")] + public int CompletedAttempts { get; set; } + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIRoomScore.cs b/osu.Game/Online/API/Requests/Responses/APIScoreToken.cs similarity index 90% rename from osu.Game/Online/API/Requests/Responses/APIRoomScore.cs rename to osu.Game/Online/API/Requests/Responses/APIScoreToken.cs index 9bf67836f6..6a0ecd37c7 100644 --- a/osu.Game/Online/API/Requests/Responses/APIRoomScore.cs +++ b/osu.Game/Online/API/Requests/Responses/APIScoreToken.cs @@ -5,7 +5,7 @@ using Newtonsoft.Json; namespace osu.Game.Online.API.Requests.Responses { - public class APIRoomScore + public class APIScoreToken { [JsonProperty("id")] public int ID { get; set; } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index d6c7c28840..f61a1dde43 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -3,19 +3,20 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json; using osu.Framework.Allocation; using osu.Game.Graphics; using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Online.Multiplayer; using osu.Game.Scoring; namespace osu.Game.Screens.Multi.Match.Components { - public class MatchLeaderboard : Leaderboard + public class MatchLeaderboard : Leaderboard { - public Action> ScoresLoaded; + public Action> ScoresLoaded; private readonly Room room; @@ -34,7 +35,7 @@ namespace osu.Game.Screens.Multi.Match.Components }, true); } - protected override APIRequest FetchScores(Action> scoresCallback) + protected override APIRequest FetchScores(Action> scoresCallback) { if (room.RoomID == null) return null; @@ -50,24 +51,12 @@ namespace osu.Game.Screens.Multi.Match.Components return req; } - protected override LeaderboardScore CreateDrawableScore(RoomScore model, int index) => new MatchLeaderboardScore(model, index); - - private class GetRoomScoresRequest : APIRequest> - { - private readonly int roomId; - - public GetRoomScoresRequest(int roomId) - { - this.roomId = roomId; - } - - protected override string Target => $@"rooms/{roomId}/leaderboard"; - } + protected override LeaderboardScore CreateDrawableScore(APIRoomScoreInfo model, int index) => new MatchLeaderboardScore(model, index); } public class MatchLeaderboardScore : LeaderboardScore { - public MatchLeaderboardScore(RoomScore score, int rank) + public MatchLeaderboardScore(APIRoomScoreInfo score, int rank) : base(score, rank) { } @@ -81,8 +70,8 @@ namespace osu.Game.Screens.Multi.Match.Components protected override IEnumerable GetStatistics(ScoreInfo model) => new[] { new LeaderboardScoreStatistic(FontAwesome.fa_crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)), - new LeaderboardScoreStatistic(FontAwesome.fa_refresh, "Total Attempts", ((RoomScore)model).TotalAttempts.ToString()), - new LeaderboardScoreStatistic(FontAwesome.fa_check, "Completed Beatmaps", ((RoomScore)model).CompletedAttempts.ToString()), + new LeaderboardScoreStatistic(FontAwesome.fa_refresh, "Total Attempts", ((APIRoomScoreInfo)model).TotalAttempts.ToString()), + new LeaderboardScoreStatistic(FontAwesome.fa_check, "Completed Beatmaps", ((APIRoomScoreInfo)model).CompletedAttempts.ToString()), }; } @@ -90,13 +79,4 @@ namespace osu.Game.Screens.Multi.Match.Components { Overall } - - public class RoomScore : ScoreInfo - { - [JsonProperty("attempts")] - public int TotalAttempts { get; set; } - - [JsonProperty("completed")] - public int CompletedAttempts { get; set; } - } } diff --git a/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs b/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs index 6c46973ca7..e277a83bb4 100644 --- a/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs +++ b/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Lists; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Multiplayer; using osu.Game.Scoring; using osu.Game.Screens.Multi.Match.Components; @@ -73,13 +74,13 @@ namespace osu.Game.Screens.Multi.Ranking.Pages leaderboard.ScoresLoaded = scoresLoaded; } - private void scoresLoaded(IEnumerable scores) + private void scoresLoaded(IEnumerable scores) { Action gray = s => s.Colour = colours.Gray8; rankText.AddText("You are placed ", gray); - int index = scores.IndexOf(new RoomScore { User = Score.User }, new FuncEqualityComparer((s1, s2) => s1.User.Id.Equals(s2.User.Id))); + int index = scores.IndexOf(new APIRoomScoreInfo { User = Score.User }, new FuncEqualityComparer((s1, s2) => s1.User.Id.Equals(s2.User.Id))); rankText.AddText($"#{index + 1} ", s => { From baed0ef3baa1f5df34d7af86cf449f41289f1c9a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 15:46:04 +0900 Subject: [PATCH 118/220] Rename variable --- osu.Game.Tests/Visual/TestCaseMultiResults.cs | 2 +- osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs | 2 +- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMultiResults.cs b/osu.Game.Tests/Visual/TestCaseMultiResults.cs index deb5d88ad2..607a8cff3e 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiResults.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiResults.cs @@ -118,7 +118,7 @@ namespace osu.Game.Tests.Visual Accuracy = 0.98, TotalScore = 987654, TotalAttempts = 13, - CompletedAttempts = 5 + CompletedBeatmaps = 5 }; } } diff --git a/osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs index 2394db3825..c6ef919e54 100644 --- a/osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs +++ b/osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs @@ -12,6 +12,6 @@ namespace osu.Game.Online.API.Requests.Responses public int TotalAttempts { get; set; } [JsonProperty("completed")] - public int CompletedAttempts { get; set; } + public int CompletedBeatmaps { get; set; } } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index f61a1dde43..4d574ff9ef 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -71,7 +71,7 @@ namespace osu.Game.Screens.Multi.Match.Components { new LeaderboardScoreStatistic(FontAwesome.fa_crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)), new LeaderboardScoreStatistic(FontAwesome.fa_refresh, "Total Attempts", ((APIRoomScoreInfo)model).TotalAttempts.ToString()), - new LeaderboardScoreStatistic(FontAwesome.fa_check, "Completed Beatmaps", ((APIRoomScoreInfo)model).CompletedAttempts.ToString()), + new LeaderboardScoreStatistic(FontAwesome.fa_check, "Completed Beatmaps", ((APIRoomScoreInfo)model).CompletedBeatmaps.ToString()), }; } From bb08bf10a08d86bc214dc333988bd77a46a142d1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 16:26:27 +0900 Subject: [PATCH 119/220] Fix post-merge issues --- osu.Game.Tests/Visual/TestCaseMultiResults.cs | 16 ++++-------- .../Screens/Multi/Ranking/MultiResults.cs | 8 +++--- .../Ranking/Pages/RoomRankingResultsPage.cs | 2 +- ...sultType.cs => RoomLeaderboardPageInfo.cs} | 9 ++++--- osu.Game/Screens/Play/Player.cs | 5 +++- .../Ranking/{Pages => }/ResultsPage.cs | 2 +- osu.Game/Screens/Ranking/Types/IResultType.cs | 15 ----------- .../Ranking/Types/RankingResultType.cs | 26 ------------------- .../Screens/Ranking/Types/ScoreResultType.cs | 26 ------------------- 9 files changed, 20 insertions(+), 89 deletions(-) rename osu.Game/Screens/Multi/Ranking/Types/{RoomRankingResultType.cs => RoomLeaderboardPageInfo.cs} (76%) rename osu.Game/Screens/Ranking/{Pages => }/ResultsPage.cs (98%) delete mode 100644 osu.Game/Screens/Ranking/Types/IResultType.cs delete mode 100644 osu.Game/Screens/Ranking/Types/RankingResultType.cs delete mode 100644 osu.Game/Screens/Ranking/Types/ScoreResultType.cs diff --git a/osu.Game.Tests/Visual/TestCaseMultiResults.cs b/osu.Game.Tests/Visual/TestCaseMultiResults.cs index 607a8cff3e..38027e0bc3 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiResults.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiResults.cs @@ -14,8 +14,7 @@ using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Ranking; using osu.Game.Screens.Multi.Ranking.Pages; using osu.Game.Screens.Multi.Ranking.Types; -using osu.Game.Screens.Ranking.Pages; -using osu.Game.Screens.Ranking.Types; +using osu.Game.Screens.Ranking; using osu.Game.Users; namespace osu.Game.Tests.Visual @@ -25,7 +24,7 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(MultiResults), - typeof(RoomRankingResultType), + typeof(RoomLeaderboardPageInfo), typeof(RoomRankingResultsPage) }; @@ -60,21 +59,16 @@ namespace osu.Game.Tests.Visual this.room = room; } - protected override IEnumerable CreateResultTypes() => new IResultType[] - { - new ScoreResultType(Score, Beatmap), - new RankingResultType(Score, Beatmap), - new TestRoomRankingResultType(Score, Beatmap, room), - }; + protected override IEnumerable CreateResultPages() => new[] { new TestRoomLeaderboardPageInfo(Score, Beatmap, room) }; } - private class TestRoomRankingResultType : RoomRankingResultType + private class TestRoomLeaderboardPageInfo : RoomLeaderboardPageInfo { private readonly ScoreInfo score; private readonly WorkingBeatmap beatmap; private readonly Room room; - public TestRoomRankingResultType(ScoreInfo score, WorkingBeatmap beatmap, Room room) + public TestRoomLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap, Room room) : base(score, beatmap, room) { this.score = score; diff --git a/osu.Game/Screens/Multi/Ranking/MultiResults.cs b/osu.Game/Screens/Multi/Ranking/MultiResults.cs index 4358943057..0fffe250bf 100644 --- a/osu.Game/Screens/Multi/Ranking/MultiResults.cs +++ b/osu.Game/Screens/Multi/Ranking/MultiResults.cs @@ -20,11 +20,11 @@ namespace osu.Game.Screens.Multi.Ranking this.room = room; } - protected override IEnumerable CreateResultTypes() => new IResultType[] + protected override IEnumerable CreateResultPages() => new IResultPageInfo[] { - new ScoreResultType(Score, Beatmap), - new RankingResultType(Score, Beatmap), - new RoomRankingResultType(Score, Beatmap, room), + new ScoreOverviewPageInfo(Score, Beatmap), + new BeatmapLeaderboardPageInfo(Score, Beatmap), + new RoomLeaderboardPageInfo(Score, Beatmap, room), }; } } diff --git a/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs b/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs index e277a83bb4..a3836ed82a 100644 --- a/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs +++ b/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs @@ -16,7 +16,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Multiplayer; using osu.Game.Scoring; using osu.Game.Screens.Multi.Match.Components; -using osu.Game.Screens.Ranking.Pages; +using osu.Game.Screens.Ranking; namespace osu.Game.Screens.Multi.Ranking.Pages { diff --git a/osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs b/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs similarity index 76% rename from osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs rename to osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs index 963a9ff1cf..07429b0b89 100644 --- a/osu.Game/Screens/Multi/Ranking/Types/RoomRankingResultType.cs +++ b/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs @@ -6,18 +6,17 @@ using osu.Game.Graphics; using osu.Game.Online.Multiplayer; using osu.Game.Scoring; using osu.Game.Screens.Multi.Ranking.Pages; -using osu.Game.Screens.Ranking.Pages; -using osu.Game.Screens.Ranking.Types; +using osu.Game.Screens.Ranking; namespace osu.Game.Screens.Multi.Ranking.Types { - public class RoomRankingResultType : IResultType + public class RoomLeaderboardPageInfo : IResultPageInfo { private readonly ScoreInfo score; private readonly WorkingBeatmap beatmap; private readonly Room room; - public RoomRankingResultType(ScoreInfo score, WorkingBeatmap beatmap, Room room) + public RoomLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap, Room room) { this.score = score; this.beatmap = beatmap; @@ -26,6 +25,8 @@ namespace osu.Game.Screens.Multi.Ranking.Types public FontAwesome Icon => FontAwesome.fa_list; + public string Name => "Room Leaderboard"; + public virtual ResultsPage CreatePage() => new RoomRankingResultsPage(score, beatmap, room); } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 1429675ddd..f2390318b0 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -28,6 +28,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; +using osu.Game.Screens.Ranking; using osu.Game.Skinning; using osu.Game.Storyboards.Drawables; @@ -287,7 +288,7 @@ namespace osu.Game.Screens.Play if (RulesetContainer.Replay == null) scoreManager.Import(score, true); - Push(new SoloResults(score)); + Push(CreateResults(score)); onCompletionEvent = null; }); @@ -431,5 +432,7 @@ namespace osu.Game.Screens.Play if (storyboardVisible && beatmap.Storyboard.ReplacesBackground) Background?.FadeTo(0, BACKGROUND_FADE_DURATION, Easing.OutQuint); } + + protected virtual Results CreateResults(ScoreInfo score) => new SoloResults(score); } } diff --git a/osu.Game/Screens/Ranking/Pages/ResultsPage.cs b/osu.Game/Screens/Ranking/ResultsPage.cs similarity index 98% rename from osu.Game/Screens/Ranking/Pages/ResultsPage.cs rename to osu.Game/Screens/Ranking/ResultsPage.cs index 3f077f5759..08c6155557 100644 --- a/osu.Game/Screens/Ranking/Pages/ResultsPage.cs +++ b/osu.Game/Screens/Ranking/ResultsPage.cs @@ -12,7 +12,7 @@ using osu.Game.Scoring; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Ranking.Pages +namespace osu.Game.Screens.Ranking { public abstract class ResultsPage : Container { diff --git a/osu.Game/Screens/Ranking/Types/IResultType.cs b/osu.Game/Screens/Ranking/Types/IResultType.cs deleted file mode 100644 index df574e99f1..0000000000 --- a/osu.Game/Screens/Ranking/Types/IResultType.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Graphics; -using osu.Game.Screens.Ranking.Pages; - -namespace osu.Game.Screens.Ranking.Types -{ - public interface IResultType - { - FontAwesome Icon { get; } - - ResultsPage CreatePage(); - } -} diff --git a/osu.Game/Screens/Ranking/Types/RankingResultType.cs b/osu.Game/Screens/Ranking/Types/RankingResultType.cs deleted file mode 100644 index a11732d324..0000000000 --- a/osu.Game/Screens/Ranking/Types/RankingResultType.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Scoring; -using osu.Game.Screens.Ranking.Pages; - -namespace osu.Game.Screens.Ranking.Types -{ - public class RankingResultType : IResultType - { - private readonly ScoreInfo score; - private readonly WorkingBeatmap beatmap; - - public RankingResultType(ScoreInfo score, WorkingBeatmap beatmap) - { - this.score = score; - this.beatmap = beatmap; - } - - public FontAwesome Icon => FontAwesome.fa_list; - - public ResultsPage CreatePage() => new RankingResultsPage(score, beatmap); - } -} diff --git a/osu.Game/Screens/Ranking/Types/ScoreResultType.cs b/osu.Game/Screens/Ranking/Types/ScoreResultType.cs deleted file mode 100644 index 0841365528..0000000000 --- a/osu.Game/Screens/Ranking/Types/ScoreResultType.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Scoring; -using osu.Game.Screens.Ranking.Pages; - -namespace osu.Game.Screens.Ranking.Types -{ - public class ScoreResultType : IResultType - { - private readonly ScoreInfo score; - private readonly WorkingBeatmap beatmap; - - public ScoreResultType(ScoreInfo score, WorkingBeatmap beatmap) - { - this.score = score; - this.beatmap = beatmap; - } - - public FontAwesome Icon => FontAwesome.fa_asterisk; - - public ResultsPage CreatePage() => new ScoreResultsPage(score, beatmap); - } -} From 8020ac26fbcb1b8a80fce4b0392a9ec0bae8f19c Mon Sep 17 00:00:00 2001 From: VINXIS Date: Sun, 23 Dec 2018 22:14:28 -0700 Subject: [PATCH 120/220] MBMasher's FL change --- .../Difficulty/OsuPerformanceCalculator.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 5e66d43c98..17b9df5cc6 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -123,8 +123,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty if (mods.Any(h => h is OsuModFlashlight)) { - // Apply length bonus again if flashlight is on simply because it becomes a lot harder on longer maps. - aimValue *= 1.45f * lengthBonus; + // Apply object-based bonus for flashlight. + aimValue *= 1.0f + 0.35f * Math.Min(1.0f, totalHits / 200.0f) + + (numTotalHits > 200 ? 0.3f * Math.Min(1.0f, (totalHits - 200) / 300.0f) + + (numTotalHits > 500 ? (totalHits - 500) / 1200.0f : 0.0f) : 0.0f); } // Scale the aim value with accuracy _slightly_ From 227c63dd1c6fa6ae85715ab32a50381137173b9f Mon Sep 17 00:00:00 2001 From: VINXIS Date: Sun, 23 Dec 2018 22:23:43 -0700 Subject: [PATCH 121/220] numtotalhits -> totalHits --- osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 17b9df5cc6..16f0af9875 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -125,8 +125,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty { // Apply object-based bonus for flashlight. aimValue *= 1.0f + 0.35f * Math.Min(1.0f, totalHits / 200.0f) + - (numTotalHits > 200 ? 0.3f * Math.Min(1.0f, (totalHits - 200) / 300.0f) + - (numTotalHits > 500 ? (totalHits - 500) / 1200.0f : 0.0f) : 0.0f); + (totalHits > 200 ? 0.3f * Math.Min(1.0f, (totalHits - 200) / 300.0f) + + (totalHits > 500 ? (totalHits - 500) / 1200.0f : 0.0f) : 0.0f); } // Scale the aim value with accuracy _slightly_ From e0e75c733960adaac76dbcc27a570f99bafb7098 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 11:24:46 +0900 Subject: [PATCH 122/220] Fix incorrect room status --- .../Multi/Lounge/Components/DrawableRoom.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index d6bc0018e4..d62b628389 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -211,14 +211,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components }, }; - bindings.Status.ValueChanged += s => - { - status.Text = s.Message; - - foreach (Drawable d in new Drawable[] { selectionBox, sideStrip, status }) - d.FadeColour(s.GetAppropriateColour(colours), transition_duration); - }; - background.Beatmap.BindTo(bindings.CurrentBeatmap); modeTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); beatmapTitle.Beatmap.BindTo(bindings.CurrentBeatmap); @@ -228,6 +220,13 @@ namespace osu.Game.Screens.Multi.Lounge.Components bindings.Name.BindValueChanged(n => name.Text = n, true); bindings.EndDate.BindValueChanged(d => endDate.Date = d, true); + bindings.Status.BindValueChanged(s => + { + status.Text = s.Message; + + foreach (Drawable d in new Drawable[] { selectionBox, sideStrip, status }) + d.FadeColour(s.GetAppropriateColour(colours), transition_duration); + }, true); } protected override void LoadComplete() From f79aa07d027cb2d2c2a71ef5c1917ecc8560f17d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 11:31:36 +0900 Subject: [PATCH 123/220] Fix enddate not being bound to --- osu.Game/Screens/Multi/RoomBindings.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/RoomBindings.cs b/osu.Game/Screens/Multi/RoomBindings.cs index b5854bf957..e84fa9c261 100644 --- a/osu.Game/Screens/Multi/RoomBindings.cs +++ b/osu.Game/Screens/Multi/RoomBindings.cs @@ -44,8 +44,9 @@ namespace osu.Game.Screens.Multi Status.UnbindFrom(room.Status); Type.UnbindFrom(room.Type); Playlist.UnbindFrom(room.Playlist); - MaxParticipants.UnbindFrom(room.MaxParticipants); Participants.UnbindFrom(room.Participants); + MaxParticipants.UnbindFrom(room.MaxParticipants); + EndDate.UnbindFrom(room.EndDate); Availability.UnbindFrom(room.Availability); Duration.UnbindFrom(room.Duration); } @@ -59,8 +60,9 @@ namespace osu.Game.Screens.Multi Status.BindTo(room.Status); Type.BindTo(room.Type); Playlist.BindTo(room.Playlist); - MaxParticipants.BindTo(room.MaxParticipants); Participants.BindTo(room.Participants); + MaxParticipants.BindTo(room.MaxParticipants); + EndDate.BindTo(room.EndDate); Availability.BindTo(room.Availability); Duration.BindTo(room.Duration); } From 6712a687972c2fcc347846e5f021a3187342f797 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 11:45:50 +0900 Subject: [PATCH 124/220] Create IRoomManager interface, add test for RoomsContainer --- .../Visual/TestCaseLoungeRoomsContainer.cs | 86 +++++++++++++++++++ osu.Game/Screens/Multi/IRoomManager.cs | 46 ++++++++++ .../Multi/Lounge/Components/RoomsContainer.cs | 4 +- osu.Game/Screens/Multi/Lounge/LoungeScreen.cs | 2 +- .../Match/Components/RoomSettingsOverlay.cs | 2 +- osu.Game/Screens/Multi/Match/MatchScreen.cs | 2 +- osu.Game/Screens/Multi/Multiplayer.cs | 2 +- osu.Game/Screens/Multi/RoomManager.cs | 4 +- 8 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs create mode 100644 osu.Game/Screens/Multi/IRoomManager.cs diff --git a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs new file mode 100644 index 0000000000..c6279767a7 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs @@ -0,0 +1,86 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi; +using osu.Game.Screens.Multi.Lounge.Components; +using osu.Game.Users; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseLoungeRoomsContainer : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(RoomsContainer), + typeof(DrawableRoom) + }; + + [Cached(Type = typeof(IRoomManager))] + private TestRoomManager roomManager = new TestRoomManager(); + + public TestCaseLoungeRoomsContainer() + { + RoomsContainer rooms; + + Child = rooms = new RoomsContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 0.5f, + JoinRequested = joinRequested + }; + + int roomId = 0; + + AddStep("Add room", () => roomManager.Rooms.Add(new Room + { + Name = { Value = $"Room {++roomId}"}, + Host = { Value = new User { Username = "Host" } }, + EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) } + })); + + AddStep("Remove selected", () => + { + if (rooms.SelectedRoom.Value != null) + roomManager.Rooms.Remove(rooms.SelectedRoom.Value); + }); + } + + private void joinRequested(Room room) => room.Status.Value = new JoinedRoomStatus(); + + private class TestRoomManager : IRoomManager + { + public event Action OpenRequested; + + public readonly BindableCollection Rooms = new BindableCollection(); + IBindableCollection IRoomManager.Rooms => Rooms; + + public void CreateRoom(Room room) => Rooms.Add(room); + + public void JoinRoom(Room room) => OpenRequested?.Invoke(room); + + public void PartRoom() + { + } + + public void Filter(FilterCriteria criteria) + { + } + } + + private class JoinedRoomStatus : RoomStatus + { + public override string Message => "Joined"; + + public override Color4 GetAppropriateColour(OsuColour colours) => colours.Yellow; + } + } +} diff --git a/osu.Game/Screens/Multi/IRoomManager.cs b/osu.Game/Screens/Multi/IRoomManager.cs new file mode 100644 index 0000000000..f09f360ea2 --- /dev/null +++ b/osu.Game/Screens/Multi/IRoomManager.cs @@ -0,0 +1,46 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Configuration; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Lounge.Components; + +namespace osu.Game.Screens.Multi +{ + public interface IRoomManager + { + /// + /// Invoked when this requests a to be opened. + /// + event Action OpenRequested; + + /// + /// All the active s. + /// + IBindableCollection Rooms { get; } + + /// + /// Creates a new . + /// + /// The to create. + void CreateRoom(Room room); + + /// + /// Joins a . + /// + /// The to join. must be populated. + void JoinRoom(Room room); + + /// + /// Parts the currently-joined . + /// + void PartRoom(); + + /// + /// Queries for s matching a new . + /// + /// The to match. + void Filter(FilterCriteria criteria); + } +} diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index b17ddca21d..6fc544ec80 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components private readonly FillFlowContainer roomFlow; [Resolved] - private RoomManager manager { get; set; } + private IRoomManager roomManager { get; set; } public RoomsContainer() { @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components [BackgroundDependencyLoader] private void load() { - rooms.BindTo(manager.Rooms); + rooms.BindTo(roomManager.Rooms); rooms.ItemsAdded += addRooms; rooms.ItemsRemoved += removeRooms; diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index 8be7afad8b..82d593033f 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Multi.Lounge private readonly Action pushGameplayScreen; [Resolved(CanBeNull = true)] - private RoomManager roomManager { get; set; } + private IRoomManager roomManager { get; set; } public override string Title => "Lounge"; diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index db29722025..797894e93c 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -40,7 +40,7 @@ namespace osu.Game.Screens.Multi.Match.Components private readonly Room room; [Resolved(CanBeNull = true)] - private RoomManager manager { get; set; } + private IRoomManager manager { get; set; } public RoomSettingsOverlay(Room room) { diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 927b786ab5..dbbdbb8c54 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -40,7 +40,7 @@ namespace osu.Game.Screens.Multi.Match private OsuGame game { get; set; } [Resolved(CanBeNull = true)] - private RoomManager manager { get; set; } + private IRoomManager manager { get; set; } public MatchScreen(Room room, Action pushGameplayScreen) { diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 116d4137d5..7a8f9f3948 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Multi private OsuScreen currentScreen; - [Cached] + [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; public Multiplayer() diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 17c3229b1a..4bd9307bfb 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -17,12 +17,12 @@ using osu.Game.Screens.Multi.Lounge.Components; namespace osu.Game.Screens.Multi { - public class RoomManager : PollingComponent + public class RoomManager : PollingComponent, IRoomManager { public event Action OpenRequested; - public IBindableCollection Rooms => rooms; private readonly BindableCollection rooms = new BindableCollection(); + public IBindableCollection Rooms => rooms; private Room currentRoom; From 626ec85ae833705b6b63445b53f461247b6e3622 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 11:58:28 +0900 Subject: [PATCH 125/220] Remove IHasFilterableChildren from class --- .../Screens/Multi/Lounge/Components/RoomsContainer.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 6fc544ec80..8f4a88d406 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Screens.Multi.Lounge.Components { - public class RoomsContainer : CompositeDrawable, IHasFilterableChildren + public class RoomsContainer : CompositeDrawable { public Action JoinRequested; @@ -114,11 +114,5 @@ namespace osu.Game.Screens.Multi.Lounge.Components selectedRoom.Value = room; } - - public IEnumerable FilterTerms => Enumerable.Empty(); - - public IEnumerable FilterableChildren => InternalChildren.OfType(); - - public bool MatchingFilter { set { } } } } From 23d21a45e5dae455c2c5be8dc3b2e0d49e9d740a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 11:59:08 +0900 Subject: [PATCH 126/220] More automated tests --- .../Visual/TestCaseLoungeRoomsContainer.cs | 39 ++++++++++++------- .../Multi/Lounge/Components/RoomsContainer.cs | 1 + 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs index c6279767a7..916468ae2f 100644 --- a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -28,9 +29,9 @@ namespace osu.Game.Tests.Visual public TestCaseLoungeRoomsContainer() { - RoomsContainer rooms; + RoomsContainer container; - Child = rooms = new RoomsContainer + Child = container = new RoomsContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -38,20 +39,32 @@ namespace osu.Game.Tests.Visual JoinRequested = joinRequested }; - int roomId = 0; + AddStep("clear rooms", () => roomManager.Rooms.Clear()); - AddStep("Add room", () => roomManager.Rooms.Add(new Room + AddStep("add rooms", () => { - Name = { Value = $"Room {++roomId}"}, - Host = { Value = new User { Username = "Host" } }, - EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) } - })); - - AddStep("Remove selected", () => - { - if (rooms.SelectedRoom.Value != null) - roomManager.Rooms.Remove(rooms.SelectedRoom.Value); + for (int i = 0; i < 3; i++) + { + roomManager.Rooms.Add(new Room + { + RoomID = { Value = i }, + Name = { Value = $"Room {i}" }, + Host = { Value = new User { Username = "Host" } }, + EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) } + }); + } }); + + AddAssert("has 2 rooms", () => container.Rooms.Count == 3); + AddStep("remove first room", () => roomManager.Rooms.Remove(roomManager.Rooms.FirstOrDefault())); + AddAssert("has 2 rooms", () => container.Rooms.Count == 2); + AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID.Value != 0)); + + AddStep("select first room", () => container.Rooms.First().Action?.Invoke()); + AddAssert("first room selected", () => container.SelectedRoom.Value == roomManager.Rooms.First()); + + AddStep("join first room", () => container.Rooms.First().Action?.Invoke()); + AddAssert("first room joined", () => roomManager.Rooms.First().Status.Value is JoinedRoomStatus); } private void joinRequested(Room room) => room.Status.Value = new JoinedRoomStatus(); diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 8f4a88d406..33b71d1203 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -25,6 +25,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components private readonly IBindableCollection rooms = new BindableCollection(); private readonly FillFlowContainer roomFlow; + public IReadOnlyList Rooms => roomFlow; [Resolved] private IRoomManager roomManager { get; set; } From 91b83cd4b8fb0de51685756c708fa23ef83070c9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 13:57:25 +0900 Subject: [PATCH 127/220] Fix leaderboard being queried on room creation --- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 4d574ff9ef..dd5a73817f 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -28,8 +28,11 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load() { - room.RoomID.BindValueChanged(_ => + room.RoomID.BindValueChanged(id => { + if (id == null) + return; + Scores = null; UpdateScores(); }, true); From d4f5a8507c5dd4763161a0c9e83f8b22da8cefa8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 17:14:56 +0900 Subject: [PATCH 128/220] Exit from match screen on escape --- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 8 ++++++-- osu.Game/Screens/Multi/Match/MatchScreen.cs | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 1ec138ab57..576a1d619a 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -19,10 +19,10 @@ namespace osu.Game.Online.Chat /// public class StandAloneChatDisplay : CompositeDrawable { - private readonly bool postingTextbox; - public readonly Bindable Channel = new Bindable(); + public Action Exit; + private readonly FocusedTextBox textbox; protected ChannelManager ChannelManager; @@ -31,6 +31,8 @@ namespace osu.Game.Online.Chat private DrawableChannel drawableChannel; + private readonly bool postingTextbox; + private const float textbox_height = 30; /// @@ -66,6 +68,8 @@ namespace osu.Game.Online.Chat Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, }); + + textbox.Exit += () => Exit?.Invoke(); } Channel.BindValueChanged(channelChanged); diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index dbbdbb8c54..9f1bbfdb4e 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -28,6 +28,7 @@ namespace osu.Game.Screens.Multi.Match private readonly RoomBindings bindings = new RoomBindings(); private readonly MatchLeaderboard leaderboard; + private readonly Action pushGameplayScreen; [Cached] @@ -49,6 +50,7 @@ namespace osu.Game.Screens.Multi.Match bindings.Room = room; + MatchChatDisplay chat; Components.Header header; RoomSettingsOverlay settings; @@ -71,7 +73,7 @@ namespace osu.Game.Screens.Multi.Match new Drawable[] { leaderboard = new MatchLeaderboard(room) { RelativeSizeAxes = Axes.Both }, - new MatchChatDisplay(room) { RelativeSizeAxes = Axes.Both } + chat = new MatchChatDisplay(room) { RelativeSizeAxes = Axes.Both } }, }, } @@ -100,6 +102,8 @@ namespace osu.Game.Screens.Multi.Match else settings.Hide(); }; + + chat.Exit += Exit; } protected override void LoadComplete() From 2f32c4d4d1d4edb62a167746e7203d481773edff Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 17:17:51 +0900 Subject: [PATCH 129/220] Fix title of match song select --- osu.Game/Screens/Select/MatchSongSelect.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 2008c9b783..f5ce34ea25 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using Humanizer; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi; @@ -12,6 +13,7 @@ namespace osu.Game.Screens.Select public Action Selected; public string ShortTitle => "song selection"; + public override string Title => ShortTitle.Humanize(); protected override bool OnStart() { From 9542e3e24ada33a0d63030584b7c109f940a1ab3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Dec 2018 17:59:28 +0900 Subject: [PATCH 130/220] Add Updateable beatmap sprite --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- .../UpdateableBeatmapBackgroundSprite.cs | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index c179821a7c..58c0819075 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps /// /// A default representation of a WorkingBeatmap to use when no beatmap is available. /// - public WorkingBeatmap DefaultBeatmap { private get; set; } + public WorkingBeatmap DefaultBeatmap { get; set; } public override string[] HandledExtensions => new[] { ".osz" }; diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs new file mode 100644 index 0000000000..1808325466 --- /dev/null +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -0,0 +1,47 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Beatmaps.Drawables +{ + /// + /// Display a baetmap background from a local source, but fallback to online source if not available. + /// + public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable + { + public readonly IBindable Beatmap = new Bindable(); + + [Resolved] + private BeatmapManager beatmaps { get; set; } + + public UpdateableBeatmapBackgroundSprite() + { + Beatmap.BindValueChanged(b => Schedule(() => Model = b)); + } + + protected override Drawable CreateDrawable(BeatmapInfo model) + { + Drawable drawable; + + var localBeatmap = beatmaps.GetWorkingBeatmap(model); + + if (localBeatmap == beatmaps.DefaultBeatmap && model?.BeatmapSet?.OnlineInfo != null) + drawable = new BeatmapSetCover(model.BeatmapSet); + else + drawable = new BeatmapBackgroundSprite(localBeatmap); + + drawable.RelativeSizeAxes = Axes.Both; + drawable.Anchor = Anchor.Centre; + drawable.Origin = Anchor.Centre; + drawable.FillMode = FillMode.Fill; + + return drawable; + } + + protected override double FadeDuration => 400; + } +} From 1dd2a4e3680cd26eb1014f281220a3d698b8510f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 18:07:19 +0900 Subject: [PATCH 131/220] Fix host info not working --- .../Visual/TestCaseMatchHostInfo.cs | 10 +++++-- .../Multi/Match/Components/HostInfo.cs | 30 ++++++++++++------- .../Screens/Multi/Match/Components/Info.cs | 4 ++- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs index 006af2e10e..8e733d388a 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs @@ -3,8 +3,8 @@ using System; using System.Collections.Generic; +using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Users; @@ -17,13 +17,19 @@ namespace osu.Game.Tests.Visual typeof(HostInfo) }; + private readonly Bindable host = new Bindable(new User { Username = "SomeHost" }); + public TestCaseMatchHostInfo() { - Child = new HostInfo(new Room { Host = { Value = new User { Username = "ImAHost" }}}) + HostInfo hostInfo; + + Child = hostInfo = new HostInfo { Anchor = Anchor.Centre, Origin = Anchor.Centre }; + + hostInfo.Host.BindTo(host); } } } diff --git a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs index 01b84bd40b..437b4cfe1b 100644 --- a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs +++ b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs @@ -1,11 +1,11 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Containers; using osu.Game.Online.Chat; -using osu.Game.Online.Multiplayer; using osu.Game.Users; using osuTK; @@ -13,13 +13,16 @@ namespace osu.Game.Screens.Multi.Match.Components { public class HostInfo : CompositeDrawable { - public HostInfo(Room room) + public readonly IBindable Host = new Bindable(); + + private readonly LinkFlowContainer linkContainer; + private readonly UpdateableAvatar avatar; + + public HostInfo() { AutoSizeAxes = Axes.X; Height = 50; - LinkFlowContainer linkContainer; - InternalChild = new FillFlowContainer { AutoSizeAxes = Axes.Both, @@ -27,11 +30,7 @@ namespace osu.Game.Screens.Multi.Match.Components Spacing = new Vector2(5, 0), Children = new Drawable[] { - new UpdateableAvatar - { - Size = new Vector2(50), - User = room.Host.Value - }, + avatar = new UpdateableAvatar { Size = new Vector2(50) }, new FillFlowContainer { Anchor = Anchor.CentreLeft, @@ -43,11 +42,20 @@ namespace osu.Game.Screens.Multi.Match.Components } }; - if (room.Host.Value != null) + + + Host.BindValueChanged(updateHost); + } + + private void updateHost(User host) + { + avatar.User = host; + + if (host != null) { linkContainer.AddText("hosted by"); linkContainer.NewLine(); - linkContainer.AddLink(room.Host.Value.Username, null, LinkAction.OpenUserProfile, room.Host.Value.Id.ToString(), "View Profile", s => s.Font = "Exo2.0-BoldItalic"); + linkContainer.AddLink(host.Username, null, LinkAction.OpenUserProfile, host.Id.ToString(), "View Profile", s => s.Font = "Exo2.0-BoldItalic"); } } } diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index ca1ca5f40f..08ba370282 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -35,6 +35,7 @@ namespace osu.Game.Screens.Multi.Match.Components ViewBeatmapButton viewBeatmapButton; OsuSpriteText name; EndDateInfo endDate; + HostInfo hostInfo; Children = new Drawable[] { @@ -69,7 +70,7 @@ namespace osu.Game.Screens.Multi.Match.Components endDate = new EndDateInfo { TextSize = 14 } } }, - new HostInfo(room), + hostInfo = new HostInfo(), }, }, new FillFlowContainer @@ -95,6 +96,7 @@ namespace osu.Game.Screens.Multi.Match.Components viewBeatmapButton.Beatmap.BindTo(bindings.CurrentBeatmap); readyButton.Beatmap.BindTo(bindings.CurrentBeatmap); + hostInfo.Host.BindTo(bindings.Host); bindings.Availability.BindValueChanged(_ => updateAvailabilityStatus()); bindings.Status.BindValueChanged(_ => updateAvailabilityStatus()); From 6a5f0eca1813bc67b631da799b3f46fee5aa2fa6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 18:07:50 +0900 Subject: [PATCH 132/220] Fix various elements flashing --- osu.Game/Online/Multiplayer/Room.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 16b0c588fa..ef07fe4aa6 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -71,16 +71,25 @@ namespace osu.Game.Online.Multiplayer { RoomID.Value = other.RoomID; Name.Value = other.Name; - Host.Value = other.Host; - Status.Value = other.Status; + + if (other.Host.Value != null && Host.Value?.Id != other.Host.Value.Id) + Host.Value = other.Host; + + if (Status.Value.GetType() != other.Status.Value.GetType()) + Status.Value = other.Status; + Availability.Value = other.Availability; - Type.Value = other.Type; + + if (Type.Value.GetType() != other.Type.Value.GetType()) + Type.Value = other.Type; + MaxParticipants.Value = other.MaxParticipants; Participants.Value = other.Participants.Value.ToArray(); EndDate.Value = other.EndDate; - Playlist.Clear(); - Playlist.AddRange(other.Playlist); + // Todo: Temporary, should only remove/add new items (requires framework changes) + if (Playlist.Count == 0) + Playlist.AddRange(other.Playlist); } public bool ShouldSerializeRoomID() => false; From 96c9e5f209bf6e9b8077997cd902a1a3987eb18d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Dec 2018 18:34:45 +0900 Subject: [PATCH 133/220] Make DefaultBeatmap readonly --- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 5 +---- osu.Game/Beatmaps/BeatmapManager.cs | 15 +++++++++------ osu.Game/OsuGameBase.cs | 9 ++++----- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index d87a8d0056..29060ceb12 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -87,10 +87,7 @@ namespace osu.Game.Tests.Visual usage.Migrate(); Dependencies.Cache(rulesets = new RulesetStore(factory)); - Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null) - { - DefaultBeatmap = defaultBeatmap = Beatmap.Default - }); + Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null, null, defaultBeatmap = Beatmap.Default)); Beatmap.SetDefault(); } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 58c0819075..73fd5da22c 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps /// /// A default representation of a WorkingBeatmap to use when no beatmap is available. /// - public WorkingBeatmap DefaultBeatmap { get; set; } + public readonly WorkingBeatmap DefaultBeatmap; public override string[] HandledExtensions => new[] { ".osz" }; @@ -77,16 +77,19 @@ namespace osu.Game.Beatmaps private readonly List currentDownloads = new List(); - public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null) + public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null, + WorkingBeatmap defaultBeatmap = null) : base(storage, contextFactory, new BeatmapStore(contextFactory), importHost) { - beatmaps = (BeatmapStore)ModelStore; - beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b); - beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b); - this.rulesets = rulesets; this.api = api; this.audioManager = audioManager; + + DefaultBeatmap = defaultBeatmap; + + beatmaps = (BeatmapStore)ModelStore; + beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b); + beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b); } protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 0f1819d55b..002ef6ec32 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -153,9 +153,12 @@ namespace osu.Game dependencies.Cache(API); dependencies.CacheAs(API); + var defaultBeatmap = new DummyWorkingBeatmap(this); + beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio); + dependencies.Cache(RulesetStore = new RulesetStore(contextFactory)); dependencies.Cache(FileStore = new FileStore(contextFactory, Host.Storage)); - dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, API, Audio, Host)); + dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, API, Audio, Host, defaultBeatmap)); dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, BeatmapManager, Host.Storage, contextFactory, Host)); dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore)); dependencies.Cache(SettingsStore = new SettingsStore(contextFactory)); @@ -166,10 +169,6 @@ namespace osu.Game fileImporters.Add(ScoreManager); fileImporters.Add(SkinManager); - var defaultBeatmap = new DummyWorkingBeatmap(this); - beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio); - BeatmapManager.DefaultBeatmap = defaultBeatmap; - // tracks play so loud our samples can't keep up. // this adds a global reduction of track volume for the time being. Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8)); From c45c34d400003910f02638d359889222cc7fc3a3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Dec 2018 19:17:21 +0900 Subject: [PATCH 134/220] Make beatmap importing possible elsewhere in tests --- .../Beatmaps/IO/ImportBeatmapTest.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 26167cb24a..c8fd531fcc 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -29,7 +29,7 @@ namespace osu.Game.Tests.Beatmaps.IO { try { - loadOszIntoOsu(loadOsu(host)); + LoadOszIntoOsu(loadOsu(host)); } finally { @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Beatmaps.IO { var osu = loadOsu(host); - var imported = loadOszIntoOsu(osu); + var imported = LoadOszIntoOsu(osu); deleteBeatmapSet(imported, osu); } @@ -69,8 +69,8 @@ namespace osu.Game.Tests.Beatmaps.IO { var osu = loadOsu(host); - var imported = loadOszIntoOsu(osu); - var importedSecondTime = loadOszIntoOsu(osu); + var imported = LoadOszIntoOsu(osu); + var importedSecondTime = LoadOszIntoOsu(osu); // check the newly "imported" beatmap is actually just the restored previous import. since it matches hash. Assert.IsTrue(imported.ID == importedSecondTime.ID); @@ -105,7 +105,7 @@ namespace osu.Game.Tests.Beatmaps.IO manager.ItemAdded += (_, __, ___) => fireCount++; manager.ItemRemoved += _ => fireCount++; - var imported = loadOszIntoOsu(osu); + var imported = LoadOszIntoOsu(osu); Assert.AreEqual(0, fireCount -= 1); @@ -160,12 +160,12 @@ namespace osu.Game.Tests.Beatmaps.IO var osu = loadOsu(host); var manager = osu.Dependencies.Get(); - var imported = loadOszIntoOsu(osu); + var imported = LoadOszIntoOsu(osu); imported.Hash += "-changed"; manager.Update(imported); - var importedSecondTime = loadOszIntoOsu(osu); + var importedSecondTime = LoadOszIntoOsu(osu); Assert.IsTrue(imported.ID != importedSecondTime.ID); Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID); @@ -191,11 +191,11 @@ namespace osu.Game.Tests.Beatmaps.IO { var osu = loadOsu(host); - var imported = loadOszIntoOsu(osu); + var imported = LoadOszIntoOsu(osu); deleteBeatmapSet(imported, osu); - var importedSecondTime = loadOszIntoOsu(osu); + var importedSecondTime = LoadOszIntoOsu(osu); // check the newly "imported" beatmap is actually just the restored previous import. since it matches hash. Assert.IsTrue(imported.ID == importedSecondTime.ID); @@ -262,7 +262,7 @@ namespace osu.Game.Tests.Beatmaps.IO } } - private string createTemporaryBeatmap() + private static string createTemporaryBeatmap() { var temp = Path.GetTempFileName() + ".osz"; File.Copy(TEST_OSZ_PATH, temp, true); @@ -270,7 +270,7 @@ namespace osu.Game.Tests.Beatmaps.IO return temp; } - private BeatmapSetInfo loadOszIntoOsu(OsuGameBase osu, string path = null) + public static BeatmapSetInfo LoadOszIntoOsu(OsuGameBase osu, string path = null) { var temp = path ?? createTemporaryBeatmap(); @@ -305,7 +305,7 @@ namespace osu.Game.Tests.Beatmaps.IO return osu; } - private void ensureLoaded(OsuGameBase osu, int timeout = 60000) + private static void ensureLoaded(OsuGameBase osu, int timeout = 60000) { IEnumerable resultSets = null; var store = osu.Dependencies.Get(); @@ -343,7 +343,7 @@ namespace osu.Game.Tests.Beatmaps.IO Assert.IsTrue(beatmap?.HitObjects.Any() == true); } - private void waitForOrAssert(Func result, string failureMessage, int timeout = 60000) + private static void waitForOrAssert(Func result, string failureMessage, int timeout = 60000) { Task task = Task.Run(() => { From c902c1587a8248d78ba6d6a13af78fc9674f4e9e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Dec 2018 19:17:32 +0900 Subject: [PATCH 135/220] Add tests and modify fallback logic --- ...stCaseUpdateableBeatmapBackgroundSprite.cs | 51 +++++++++++++++++++ .../UpdateableBeatmapBackgroundSprite.cs | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs diff --git a/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs b/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs new file mode 100644 index 0000000000..24701fccbc --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Rulesets; +using osu.Game.Tests.Beatmaps.IO; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseUpdateableBeatmapBackgroundSprite : OsuTestCase + { + private UpdateableBeatmapBackgroundSprite backgroundSprite; + + [Resolved] + private BeatmapManager beatmaps { get; set; } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osu, APIAccess api, RulesetStore rulesets) + { + Bindable beatmapBindable = new Bindable(); + + var imported = ImportBeatmapTest.LoadOszIntoOsu(osu); + + Child = backgroundSprite = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both }; + + backgroundSprite.Beatmap.BindTo(beatmapBindable); + + var req = new GetBeatmapSetRequest(1); + api.Queue(req); + + AddStep("null", () => beatmapBindable.Value = null); + + AddStep("imported", () => beatmapBindable.Value = imported.Beatmaps.First()); + + if (api.IsLoggedIn) + AddUntilStep(() => req.Result != null, "wait for api response"); + + AddStep("online", () => beatmapBindable.Value = new BeatmapInfo + { + BeatmapSet = req.Result?.ToBeatmapSet(rulesets) + }); + } + } +} diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 1808325466..fd00576d21 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -29,7 +29,7 @@ namespace osu.Game.Beatmaps.Drawables var localBeatmap = beatmaps.GetWorkingBeatmap(model); - if (localBeatmap == beatmaps.DefaultBeatmap && model?.BeatmapSet?.OnlineInfo != null) + if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null) drawable = new BeatmapSetCover(model.BeatmapSet); else drawable = new BeatmapBackgroundSprite(localBeatmap); From 3370de3c2eedfb1a38a89285459dcfd8fdb432a8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 11:53:24 +0900 Subject: [PATCH 136/220] Add rider live templates --- osu.sln.DotSettings | 121 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 112efb37f0..6b8e9dc808 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -673,6 +673,127 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste True True True + True + True + o!f – Object Initializer: Anchor&Origin + True + constant("Centre") + 0 + True + True + 2.0 + InCSharpFile + ofao + True + Anchor = Anchor.$anchor$, +Origin = Anchor.$anchor$, + True + True + o!f – InternalChildren = [] + True + True + 2.0 + InCSharpFile + ofic + True + InternalChildren = new Drawable[] +{ + $END$ +}; + True + True + o!f – new GridContainer { .. } + True + True + 2.0 + InCSharpFile + ofgc + True + new GridContainer +{ + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] { $END$ }, + new Drawable[] { } + } +}; + True + True + o!f – new FillFlowContainer { .. } + True + True + 2.0 + InCSharpFile + offf + True + new FillFlowContainer +{ + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + $END$ + } +}, + True + True + o!f – new Container { .. } + True + True + 2.0 + InCSharpFile + ofcont + True + new Container +{ + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + $END$ + } +}, + True + True + o!f – BackgroundDependencyLoader load() + True + True + 2.0 + InCSharpFile + ofbdl + True + [BackgroundDependencyLoader] +private void load() +{ + $END$ +} + True + True + o!f – new Box { .. } + True + True + 2.0 + InCSharpFile + ofbox + True + new Box +{ + Colour = Color4.Black, + RelativeSizeAxes = Axes.Both, +}, + True + True + o!f – Children = [] + True + True + 2.0 + InCSharpFile + ofc + True + Children = new Drawable[] +{ + $END$ +}; True True True From e4a72c0c645103d0ee9b0553497459810fc04fa7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 13:18:36 +0900 Subject: [PATCH 137/220] Fix failing testcase --- osu.Game/Screens/Menu/ButtonSystem.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 943dfa53af..14eae54cb2 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -105,13 +105,13 @@ namespace osu.Game.Screens.Menu buttonArea.AddRange(buttonsTopLevel); } - [Resolved] + [Resolved(CanBeNull = true)] private OsuGame game { get; set; } [Resolved] private APIAccess api { get; set; } - [Resolved] + [Resolved(CanBeNull = true)] private NotificationOverlay notifications { get; set; } [BackgroundDependencyLoader(true)] @@ -128,7 +128,7 @@ namespace osu.Game.Screens.Menu { if (!api.IsLoggedIn) { - notifications.Post(new SimpleNotification + notifications?.Post(new SimpleNotification { Text = "You gotta be logged in to multi 'yo!", Icon = FontAwesome.fa_globe @@ -136,6 +136,7 @@ namespace osu.Game.Screens.Menu return; } + OnMulti?.Invoke(); } From e9556afe227f3b3ecd95ae049547d502d91d89d5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 14:26:35 +0900 Subject: [PATCH 138/220] Don't use all uppercase (is applied automatically) --- .../Multi/Match/Components/RoomSettingsOverlay.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index 797894e93c..00ebb78c18 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -72,7 +72,7 @@ namespace osu.Game.Screens.Multi.Match.Components Padding = new MarginPadding { Right = field_padding / 2 }, Children = new[] { - new Section("ROOM NAME") + new Section("Room name") { Child = NameField = new SettingsTextBox { @@ -81,12 +81,12 @@ namespace osu.Game.Screens.Multi.Match.Components OnCommit = (sender, text) => apply(), }, }, - new Section("ROOM VISIBILITY") + new Section("Room visibility") { Alpha = disabled_alpha, Child = AvailabilityPicker = new RoomAvailabilityPicker(), }, - new Section("GAME TYPE") + new Section("Game type") { Alpha = disabled_alpha, Child = new FillFlowContainer @@ -117,7 +117,7 @@ namespace osu.Game.Screens.Multi.Match.Components Padding = new MarginPadding { Left = field_padding / 2 }, Children = new[] { - new Section("MAX PARTICIPANTS") + new Section("Max participants") { Alpha = disabled_alpha, Child = MaxParticipantsField = new SettingsNumberTextBox @@ -127,7 +127,7 @@ namespace osu.Game.Screens.Multi.Match.Components OnCommit = (sender, text) => apply(), }, }, - new Section("DURATION") + new Section("Duration") { Child = DurationField = new DurationDropdown { @@ -148,7 +148,7 @@ namespace osu.Game.Screens.Multi.Match.Components } } }, - new Section("PASSWORD (OPTIONAL)") + new Section("Password (optional)") { Alpha = disabled_alpha, Child = PasswordField = new SettingsPasswordTextBox From 755c6b924396ee42ce6c25df26e8f4d04a23c760 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 15:03:35 +0900 Subject: [PATCH 139/220] Make room settings scroll --- .../Match/Components/RoomSettingsOverlay.cs | 173 +++++++++--------- 1 file changed, 91 insertions(+), 82 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index 00ebb78c18..cec4a20133 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -61,105 +61,113 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex(@"28242d"), }, - new Container + new ScrollContainer { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 35, Bottom = 75, Horizontal = SearchableListOverlay.WIDTH_PADDING }, Children = new[] { - new SectionContainer + new Container { - Padding = new MarginPadding { Right = field_padding / 2 }, - Children = new[] + Padding = new MarginPadding { Top = 35, Bottom = 75, Horizontal = SearchableListOverlay.WIDTH_PADDING }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - new Section("Room name") + new SectionContainer { - Child = NameField = new SettingsTextBox + Padding = new MarginPadding { Right = field_padding / 2 }, + Children = new[] { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - OnCommit = (sender, text) => apply(), - }, - }, - new Section("Room visibility") - { - Alpha = disabled_alpha, - Child = AvailabilityPicker = new RoomAvailabilityPicker(), - }, - new Section("Game type") - { - Alpha = disabled_alpha, - Child = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Spacing = new Vector2(7), - Children = new Drawable[] + new Section("Room name") { - TypePicker = new GameTypePicker + Child = NameField = new SettingsTextBox { RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + OnCommit = (sender, text) => apply(), }, - typeLabel = new OsuSpriteText + }, + new Section("Room visibility") + { + Alpha = disabled_alpha, + Child = AvailabilityPicker = new RoomAvailabilityPicker(), + }, + new Section("Game type") + { + Alpha = disabled_alpha, + Child = new FillFlowContainer { - TextSize = 14, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(7), + Children = new Drawable[] + { + TypePicker = new GameTypePicker + { + RelativeSizeAxes = Axes.X, + }, + typeLabel = new OsuSpriteText + { + TextSize = 14, + }, + }, + }, + }, + }, + }, + new SectionContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Padding = new MarginPadding { Left = field_padding / 2 }, + Children = new[] + { + new Section("Max participants") + { + Alpha = disabled_alpha, + Child = MaxParticipantsField = new SettingsNumberTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + OnCommit = (sender, text) => apply(), + }, + }, + new Section("Duration") + { + Child = DurationField = new DurationDropdown + { + RelativeSizeAxes = Axes.X, + Items = new[] + { + TimeSpan.FromMinutes(1), + TimeSpan.FromMinutes(30), + TimeSpan.FromHours(1), + TimeSpan.FromHours(2), + TimeSpan.FromHours(4), + TimeSpan.FromHours(8), + TimeSpan.FromHours(12), + TimeSpan.FromHours(16), + TimeSpan.FromHours(24), + TimeSpan.FromDays(3), + TimeSpan.FromDays(7) + } + } + }, + new Section("Password (optional)") + { + Alpha = disabled_alpha, + Child = PasswordField = new SettingsPasswordTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + OnCommit = (sender, text) => apply() }, }, }, }, }, - }, - new SectionContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Padding = new MarginPadding { Left = field_padding / 2 }, - Children = new[] - { - new Section("Max participants") - { - Alpha = disabled_alpha, - Child = MaxParticipantsField = new SettingsNumberTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - OnCommit = (sender, text) => apply(), - }, - }, - new Section("Duration") - { - Child = DurationField = new DurationDropdown - { - RelativeSizeAxes = Axes.X, - Items = new[] - { - TimeSpan.FromMinutes(1), - TimeSpan.FromMinutes(30), - TimeSpan.FromHours(1), - TimeSpan.FromHours(2), - TimeSpan.FromHours(4), - TimeSpan.FromHours(8), - TimeSpan.FromHours(12), - TimeSpan.FromHours(16), - TimeSpan.FromHours(24), - TimeSpan.FromDays(3), - TimeSpan.FromDays(7) - } - } - }, - new Section("Password (optional)") - { - Alpha = disabled_alpha, - Child = PasswordField = new SettingsPasswordTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - OnCommit = (sender, text) => apply() - }, - }, - }, - }, + } }, }, new Container @@ -265,7 +273,8 @@ namespace osu.Game.Screens.Multi.Match.Components { public SectionContainer() { - RelativeSizeAxes = Axes.Both; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; Width = 0.5f; Direction = FillDirection.Vertical; Spacing = new Vector2(field_padding); From 6e8c46f00bca239cfd0efa6deea08f92cf417a62 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 15:23:57 +0900 Subject: [PATCH 140/220] Fix padding and use grid container for more correctness --- .../Match/Components/RoomSettingsOverlay.cs | 240 ++++++++++-------- 1 file changed, 130 insertions(+), 110 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index cec4a20133..fc97edb103 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -61,136 +61,156 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex(@"28242d"), }, - new ScrollContainer + new GridContainer { RelativeSizeAxes = Axes.Both, - Children = new[] + RowDimensions = new[] { - new Container + new Dimension(GridSizeMode.Distributed), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] { - Padding = new MarginPadding { Top = 35, Bottom = 75, Horizontal = SearchableListOverlay.WIDTH_PADDING }, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + new ScrollContainer { - new SectionContainer + Padding = new MarginPadding { Vertical = 10 }, + RelativeSizeAxes = Axes.Both, + Children = new[] { - Padding = new MarginPadding { Right = field_padding / 2 }, - Children = new[] + new Container { - new Section("Room name") + Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - Child = NameField = new SettingsTextBox + new SectionContainer { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - OnCommit = (sender, text) => apply(), - }, - }, - new Section("Room visibility") - { - Alpha = disabled_alpha, - Child = AvailabilityPicker = new RoomAvailabilityPicker(), - }, - new Section("Game type") - { - Alpha = disabled_alpha, - Child = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Spacing = new Vector2(7), - Children = new Drawable[] + Padding = new MarginPadding { Right = field_padding / 2 }, + Children = new[] { - TypePicker = new GameTypePicker + new Section("Room name") { - RelativeSizeAxes = Axes.X, + Child = NameField = new SettingsTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + OnCommit = (sender, text) => apply(), + }, }, - typeLabel = new OsuSpriteText + new Section("Room visibility") { - TextSize = 14, + Alpha = disabled_alpha, + Child = AvailabilityPicker = new RoomAvailabilityPicker(), + }, + new Section("Game type") + { + Alpha = disabled_alpha, + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(7), + Children = new Drawable[] + { + TypePicker = new GameTypePicker + { + RelativeSizeAxes = Axes.X, + }, + typeLabel = new OsuSpriteText + { + TextSize = 14, + }, + }, + }, + }, + }, + }, + new SectionContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Padding = new MarginPadding { Left = field_padding / 2 }, + Children = new[] + { + new Section("Max participants") + { + Alpha = disabled_alpha, + Child = MaxParticipantsField = new SettingsNumberTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + OnCommit = (sender, text) => apply(), + }, + }, + new Section("Duration") + { + Child = DurationField = new DurationDropdown + { + RelativeSizeAxes = Axes.X, + Items = new[] + { + TimeSpan.FromMinutes(1), + TimeSpan.FromMinutes(30), + TimeSpan.FromHours(1), + TimeSpan.FromHours(2), + TimeSpan.FromHours(4), + TimeSpan.FromHours(8), + TimeSpan.FromHours(12), + TimeSpan.FromHours(16), + TimeSpan.FromHours(24), + TimeSpan.FromDays(3), + TimeSpan.FromDays(7) + } + } + }, + new Section("Password (optional)") + { + Alpha = disabled_alpha, + Child = PasswordField = new SettingsPasswordTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + OnCommit = (sender, text) => apply() + }, }, }, }, }, - }, - }, - new SectionContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Padding = new MarginPadding { Left = field_padding / 2 }, - Children = new[] - { - new Section("Max participants") - { - Alpha = disabled_alpha, - Child = MaxParticipantsField = new SettingsNumberTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - OnCommit = (sender, text) => apply(), - }, - }, - new Section("Duration") - { - Child = DurationField = new DurationDropdown - { - RelativeSizeAxes = Axes.X, - Items = new[] - { - TimeSpan.FromMinutes(1), - TimeSpan.FromMinutes(30), - TimeSpan.FromHours(1), - TimeSpan.FromHours(2), - TimeSpan.FromHours(4), - TimeSpan.FromHours(8), - TimeSpan.FromHours(12), - TimeSpan.FromHours(16), - TimeSpan.FromHours(24), - TimeSpan.FromDays(3), - TimeSpan.FromDays(7) - } - } - }, - new Section("Password (optional)") - { - Alpha = disabled_alpha, - Child = PasswordField = new SettingsPasswordTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - OnCommit = (sender, text) => apply() - }, - }, - }, + } }, }, + }, + new Drawable[] + { + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Y = 2, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"28242d").Darken(0.5f).Opacity(1f), + }, + ApplyButton = new CreateRoomButton + { + Margin = new MarginPadding { Vertical = 20 }, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(230, 55), + Action = apply, + }, + } + } } - }, - }, - new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Y = 2, - RelativeSizeAxes = Axes.X, - Height = 60, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"28242d").Darken(0.5f).Opacity(1f), - }, - ApplyButton = new CreateRoomButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(230, 35), - Action = apply, - }, } } }, From b2fb02709743d5db8e7446973224acedf18d3ff6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 15:26:46 +0900 Subject: [PATCH 141/220] Remove old testcase --- osu.Game.Tests/Visual/TestCaseRoomSettings.cs | 129 ------------------ 1 file changed, 129 deletions(-) delete mode 100644 osu.Game.Tests/Visual/TestCaseRoomSettings.cs diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs deleted file mode 100644 index f44c7de721..0000000000 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using NUnit.Framework; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Testing.Input; -using osu.Game.Online.Multiplayer; -using osu.Game.Screens.Multi.Match.Components; -using osuTK.Input; - -namespace osu.Game.Tests.Visual -{ - [TestFixture] - public class TestCaseRoomSettings : ManualInputManagerTestCase - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(RoomSettingsOverlay), - typeof(GameTypePicker) - }; - - private readonly Room room; - private readonly TestRoomSettingsOverlay overlay; - - public TestCaseRoomSettings() - { - room = new Room - { - Name = { Value = "One Testing Room" }, - Availability = { Value = RoomAvailability.Public }, - Type = { Value = new GameTypeTeamVersus() }, - MaxParticipants = { Value = 10 }, - }; - - Add(overlay = new TestRoomSettingsOverlay(new Room()) - { - RelativeSizeAxes = Axes.Both, - Height = 0.75f, - State = Visibility.Visible - }); - - assertAll(); - AddStep(@"set name", () => overlay.CurrentName = @"Two Testing Room"); - AddStep(@"set max", () => overlay.CurrentMaxParticipants = null); - AddStep(@"set availability", () => overlay.CurrentAvailability = RoomAvailability.InviteOnly); - AddStep(@"set type", () => overlay.CurrentType = new GameTypeTagTeam()); - apply(); - assertAll(); - AddStep(@"show", overlay.Show); - AddStep(@"set room name", () => room.Name.Value = @"Room Changed Name!"); - AddStep(@"set room availability", () => room.Availability.Value = RoomAvailability.Public); - AddStep(@"set room type", () => room.Type.Value = new GameTypeTag()); - AddStep(@"set room max", () => room.MaxParticipants.Value = 100); - assertAll(); - AddStep(@"set name", () => overlay.CurrentName = @"Unsaved Testing Room"); - AddStep(@"set max", () => overlay.CurrentMaxParticipants = 20); - AddStep(@"set availability", () => overlay.CurrentAvailability = RoomAvailability.FriendsOnly); - AddStep(@"set type", () => overlay.CurrentType = new GameTypeVersus()); - AddStep(@"hide", overlay.Hide); - AddWaitStep(5); - AddStep(@"show", overlay.Show); - assertAll(); - AddStep(@"hide", overlay.Hide); - } - - private void apply() - { - AddStep(@"apply", () => - { - overlay.ClickApplyButton(InputManager); - }); - } - - private void assertAll() - { - AddAssert(@"name == room name", () => overlay.CurrentName == room.Name.Value); - AddAssert(@"max == room max", () => overlay.CurrentMaxParticipants == room.MaxParticipants.Value); - AddAssert(@"availability == room availability", () => overlay.CurrentAvailability == room.Availability.Value); - AddAssert(@"type == room type", () => Equals(overlay.CurrentType, room.Type.Value)); - } - - private class TestRoomSettingsOverlay : RoomSettingsOverlay - { - public TestRoomSettingsOverlay(Room room) - : base(room) - { - } - - public string CurrentName - { - get => NameField.Text; - set => NameField.Text = value; - } - - public int? CurrentMaxParticipants - { - get - { - if (int.TryParse(MaxParticipantsField.Text, out int max)) - return max; - - return null; - } - set => MaxParticipantsField.Text = value?.ToString(); - } - - public RoomAvailability CurrentAvailability - { - get => AvailabilityPicker.Current.Value; - set => AvailabilityPicker.Current.Value = value; - } - - public GameType CurrentType - { - get => TypePicker.Current.Value; - set => TypePicker.Current.Value = value; - } - - public void ClickApplyButton(ManualInputManager inputManager) - { - inputManager.MoveMouseTo(ApplyButton); - inputManager.Click(MouseButton.Left); - } - } - } -} From aeb2186539bb1cd62971b02ff9839482a9955e3e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 16:06:39 +0900 Subject: [PATCH 142/220] Fix api get user request never failing --- osu.Game/Online/API/APIAccess.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 8038c1fc1f..10b4e73419 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -145,7 +145,8 @@ namespace osu.Game.Online.API if (!handleRequest(userReq)) { - Thread.Sleep(500); + if (State == APIState.Connecting) + State = APIState.Failing; continue; } From a8d0ff67a9bf0ad5e469430131999a2c630f3771 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 16:04:05 +0900 Subject: [PATCH 143/220] Add automated match settings overlay tests --- .../Visual/TestCaseMatchSettingsOverlay.cs | 93 ++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index fede2f509f..f4934e2a7d 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -3,9 +3,16 @@ using System; using System.Collections.Generic; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi; +using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Screens.Multi.Match.Components; namespace osu.Game.Tests.Visual @@ -17,13 +24,95 @@ namespace osu.Game.Tests.Visual typeof(RoomSettingsOverlay) }; - public TestCaseMatchSettingsOverlay() + [Cached(Type = typeof(IRoomManager))] + private TestRoomManager roomManager = new TestRoomManager(); + + private Room room; + private TestRoomSettings settings; + + [SetUp] + public void Setup() => Schedule(() => { - Child = new RoomSettingsOverlay(new Room()) + room = new Room(); + settings = new TestRoomSettings(room) { RelativeSizeAxes = Axes.Both, State = Visibility.Visible }; + + Child = settings; + }); + + [Test] + public void TestButtonEnabledOnlyWithNameAndBeatmap() + { + AddStep("clear name and beatmap", () => + { + room.Name.Value = ""; + room.Playlist.Clear(); + }); + + AddAssert("button disabled", () => !settings.ApplyButton.Enabled); + + AddStep("set name", () => room.Name.Value = "Room name"); + AddAssert("button disabled", () => !settings.ApplyButton.Enabled); + + AddStep("set beatmap", () => room.Playlist.Add(new PlaylistItem { Beatmap = new DummyWorkingBeatmap().BeatmapInfo })); + AddAssert("button enabled", () => settings.ApplyButton.Enabled); + + AddStep("clear name", () => room.Name.Value = ""); + AddAssert("button disabled", () => !settings.ApplyButton.Enabled); + } + + [Test] + public void TestCorrectSettingsApplied() + { + const string expected_name = "expected name"; + TimeSpan expectedDuration = TimeSpan.FromMinutes(15); + + Room createdRoom = null; + + AddStep("setup", () => + { + settings.NameField.Current.Value = expected_name; + settings.DurationField.Current.Value = expectedDuration; + + roomManager.CreateRequested = r => createdRoom = r; + }); + + AddStep("create room", () => settings.ApplyButton.Action.Invoke()); + AddAssert("has correct name", () => createdRoom.Name.Value == expected_name); + AddAssert("has correct duration", () => createdRoom.Duration.Value == expectedDuration); + } + + private class TestRoomSettings : RoomSettingsOverlay + { + public new TriangleButton ApplyButton => base.ApplyButton; + + public new OsuTextBox NameField => base.NameField; + public new OsuDropdown DurationField => base.DurationField; + + public TestRoomSettings(Room room) + : base(room) + { + } + } + + private class TestRoomManager : IRoomManager + { + public Action CreateRequested; + + public event Action OpenRequested; + + public IBindableCollection Rooms { get; } = null; + + public void CreateRoom(Room room) => CreateRequested?.Invoke(room); + + public void JoinRoom(Room room) => throw new NotImplementedException(); + + public void PartRoom() => throw new NotImplementedException(); + + public void Filter(FilterCriteria criteria) => throw new NotImplementedException(); } } } From 9b2575cc202dfe3fa7812a213ec6f356a980ab18 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 16:11:40 +0900 Subject: [PATCH 144/220] RoomSettingsOverlay -> MatchSettingOverlay --- osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs | 4 ++-- osu.Game/Online/Multiplayer/Room.cs | 2 +- osu.Game/Screens/Multi/Match/Components/Header.cs | 4 ++-- .../{RoomSettingsOverlay.cs => MatchSettingsOverlay.cs} | 4 ++-- osu.Game/Screens/Multi/Match/MatchScreen.cs | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) rename osu.Game/Screens/Multi/Match/Components/{RoomSettingsOverlay.cs => MatchSettingsOverlay.cs} (99%) diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index f4934e2a7d..322ff5bc07 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { - typeof(RoomSettingsOverlay) + typeof(MatchSettingsOverlay) }; [Cached(Type = typeof(IRoomManager))] @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Visual AddAssert("has correct duration", () => createdRoom.Duration.Value == expectedDuration); } - private class TestRoomSettings : RoomSettingsOverlay + private class TestRoomSettings : MatchSettingsOverlay { public new TriangleButton ApplyButton => base.ApplyButton; diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index ef07fe4aa6..3bad25f716 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -16,7 +16,7 @@ namespace osu.Game.Online.Multiplayer public Bindable RoomID { get; private set; } = new Bindable(); [JsonProperty("name")] - public Bindable Name { get; private set; } = new Bindable("My awesome room!"); + public Bindable Name { get; private set; } = new Bindable(); [JsonProperty("host")] public Bindable Host { get; private set; } = new Bindable(); diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index b2d39151c1..4feca7dccb 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -94,11 +94,11 @@ namespace osu.Game.Screens.Multi.Match.Components Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, Width = 200, - Padding = new MarginPadding { Vertical = 5 }, + Padding = new MarginPadding { Vertical = 10 }, Child = beatmapButton = new BeatmapSelectButton(room) { RelativeSizeAxes = Axes.Both, - Height = 1 + Height = 1, }, }, Tabs = new MatchTabControl(room) diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs similarity index 99% rename from osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs rename to osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index fc97edb103..6de2bed938 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Multi.Match.Components { - public class RoomSettingsOverlay : FocusedOverlayContainer + public class MatchSettingsOverlay : FocusedOverlayContainer { private const float transition_duration = 350; private const float field_padding = 45; @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Multi.Match.Components [Resolved(CanBeNull = true)] private IRoomManager manager { get; set; } - public RoomSettingsOverlay(Room room) + public MatchSettingsOverlay(Room room) { this.room = room; diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 9f1bbfdb4e..eb7a206163 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Multi.Match MatchChatDisplay chat; Components.Header header; - RoomSettingsOverlay settings; + MatchSettingsOverlay settings; Children = new Drawable[] { @@ -90,7 +90,7 @@ namespace osu.Game.Screens.Multi.Match { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Components.Header.HEIGHT }, - Child = settings = new RoomSettingsOverlay(room) { RelativeSizeAxes = Axes.Both }, + Child = settings = new MatchSettingsOverlay(room) { RelativeSizeAxes = Axes.Both }, }, }; From c6c8c472bb1f7f93a4551c2017473a082474686d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 16:46:50 +0900 Subject: [PATCH 145/220] Split class out --- osu.Game.Tests/Visual/TestCaseMatchHeader.cs | 3 +- osu.Game/Online/Multiplayer/GameType.cs | 152 ------------------ .../Multiplayer/GameTypes/GameTypeTag.cs | 24 +++ .../Multiplayer/GameTypes/GameTypeTagTeam.cs | 41 +++++ .../GameTypes/GameTypeTeamVersus.cs | 29 ++++ .../GameTypes/GameTypeTimeshift.cs | 22 +++ .../Multiplayer/GameTypes/GameTypeVersus.cs | 19 +++ osu.Game/Online/Multiplayer/Room.cs | 1 + osu.Game/Online/Multiplayer/VersusRow.cs | 52 ++++++ .../Multi/Match/Components/GameTypePicker.cs | 1 + osu.Game/Screens/Multi/Match/MatchScreen.cs | 3 +- osu.Game/Screens/Multi/Multiplayer.cs | 11 +- 12 files changed, 201 insertions(+), 157 deletions(-) create mode 100644 osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs create mode 100644 osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs create mode 100644 osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs create mode 100644 osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs create mode 100644 osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs create mode 100644 osu.Game/Online/Multiplayer/VersusRow.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchHeader.cs b/osu.Game.Tests/Visual/TestCaseMatchHeader.cs index ac964e22a6..4c8cdbfd19 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchHeader.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchHeader.cs @@ -1,10 +1,11 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . +// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; +using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Multi.Match.Components; diff --git a/osu.Game/Online/Multiplayer/GameType.cs b/osu.Game/Online/Multiplayer/GameType.cs index 8c9d635eea..e800142f9b 100644 --- a/osu.Game/Online/Multiplayer/GameType.cs +++ b/osu.Game/Online/Multiplayer/GameType.cs @@ -1,11 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osuTK; -using osuTK.Graphics; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; namespace osu.Game.Online.Multiplayer @@ -19,152 +15,4 @@ namespace osu.Game.Online.Multiplayer public override int GetHashCode() => GetType().GetHashCode(); public override bool Equals(object obj) => GetType() == obj?.GetType(); } - - public class GameTypeTag : GameType - { - public override string Name => "Tag"; - - public override Drawable GetIcon(OsuColour colours, float size) - { - return new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = FontAwesome.fa_refresh, - Size = new Vector2(size), - Colour = colours.Blue, - Shadow = false, - }; - } - } - - public class GameTypeVersus : GameType - { - public override string Name => "Versus"; - - public override Drawable GetIcon(OsuColour colours, float size) - { - return new VersusRow(colours.Blue, colours.Blue, size * 0.6f) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }; - } - } - - public class GameTypeTagTeam : GameType - { - public override string Name => "Tag Team"; - - public override Drawable GetIcon(OsuColour colours, float size) - { - return new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(2f), - Children = new[] - { - new SpriteIcon - { - Icon = FontAwesome.fa_refresh, - Size = new Vector2(size * 0.75f), - Colour = colours.Blue, - Shadow = false, - }, - new SpriteIcon - { - Icon = FontAwesome.fa_refresh, - Size = new Vector2(size * 0.75f), - Colour = colours.Pink, - Shadow = false, - }, - }, - }; - } - } - - public class GameTypeTeamVersus : GameType - { - public override string Name => "Team Versus"; - - public override Drawable GetIcon(OsuColour colours, float size) - { - return new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(2f), - Children = new[] - { - new VersusRow(colours.Blue, colours.Pink, size * 0.5f), - new VersusRow(colours.Blue, colours.Pink, size * 0.5f), - }, - }; - } - } - - public class VersusRow : FillFlowContainer - { - public VersusRow(Color4 first, Color4 second, float size) - { - var triangleSize = new Vector2(size); - AutoSizeAxes = Axes.Both; - Spacing = new Vector2(2f, 0f); - - Children = new[] - { - new Container - { - Size = triangleSize, - Colour = first, - Children = new[] - { - new EquilateralTriangle - { - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Both, - Rotation = 90, - EdgeSmoothness = new Vector2(1f), - }, - }, - }, - new Container - { - Size = triangleSize, - Colour = second, - Children = new[] - { - new EquilateralTriangle - { - Anchor = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Both, - Rotation = -90, - EdgeSmoothness = new Vector2(1f), - }, - }, - }, - }; - } - } - - public class GameTypeTimeshift : GameType - { - public override string Name => "Timeshift"; - - public override Drawable GetIcon(OsuColour colours, float size) => new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = FontAwesome.fa_osu_charts, - X = -2, // The icon is off-centre - Size = new Vector2(size), - Colour = colours.Blue, - Shadow = false - }; - } } diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs new file mode 100644 index 0000000000..d31439f0fe --- /dev/null +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs @@ -0,0 +1,24 @@ +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osuTK; + +namespace osu.Game.Online.Multiplayer.GameTypes +{ + public class GameTypeTag : GameType + { + public override string Name => "Tag"; + + public override Drawable GetIcon(OsuColour colours, float size) + { + return new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_refresh, + Size = new Vector2(size), + Colour = colours.Blue, + Shadow = false, + }; + } + } +} \ No newline at end of file diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs new file mode 100644 index 0000000000..74c8e76b46 --- /dev/null +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs @@ -0,0 +1,41 @@ +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osuTK; + +namespace osu.Game.Online.Multiplayer.GameTypes +{ + public class GameTypeTagTeam : GameType + { + public override string Name => "Tag Team"; + + public override Drawable GetIcon(OsuColour colours, float size) + { + return new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(2f), + Children = new[] + { + new SpriteIcon + { + Icon = FontAwesome.fa_refresh, + Size = new Vector2(size * 0.75f), + Colour = colours.Blue, + Shadow = false, + }, + new SpriteIcon + { + Icon = FontAwesome.fa_refresh, + Size = new Vector2(size * 0.75f), + Colour = colours.Pink, + Shadow = false, + }, + }, + }; + } + } +} \ No newline at end of file diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs new file mode 100644 index 0000000000..74c2c00c3b --- /dev/null +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs @@ -0,0 +1,29 @@ +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osuTK; + +namespace osu.Game.Online.Multiplayer.GameTypes +{ + public class GameTypeTeamVersus : GameType + { + public override string Name => "Team Versus"; + + public override Drawable GetIcon(OsuColour colours, float size) + { + return new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(2f), + Children = new[] + { + new VersusRow(colours.Blue, colours.Pink, size * 0.5f), + new VersusRow(colours.Blue, colours.Pink, size * 0.5f), + }, + }; + } + } +} \ No newline at end of file diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs new file mode 100644 index 0000000000..e8aa82d022 --- /dev/null +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs @@ -0,0 +1,22 @@ +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osuTK; + +namespace osu.Game.Online.Multiplayer.GameTypes +{ + public class GameTypeTimeshift : GameType + { + public override string Name => "Timeshift"; + + public override Drawable GetIcon(OsuColour colours, float size) => new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_clock_o, + X = -2, // The icon is off-centre + Size = new Vector2(size), + Colour = colours.Blue, + Shadow = false + }; + } +} \ No newline at end of file diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs new file mode 100644 index 0000000000..b6d832490f --- /dev/null +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs @@ -0,0 +1,19 @@ +using osu.Framework.Graphics; +using osu.Game.Graphics; + +namespace osu.Game.Online.Multiplayer.GameTypes +{ + public class GameTypeVersus : GameType + { + public override string Name => "Versus"; + + public override Drawable GetIcon(OsuColour colours, float size) + { + return new VersusRow(colours.Blue, colours.Blue, size * 0.6f) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; + } + } +} \ No newline at end of file diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 3bad25f716..b17d08320c 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using osu.Framework.Configuration; +using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Users; namespace osu.Game.Online.Multiplayer diff --git a/osu.Game/Online/Multiplayer/VersusRow.cs b/osu.Game/Online/Multiplayer/VersusRow.cs new file mode 100644 index 0000000000..3c7ebd936e --- /dev/null +++ b/osu.Game/Online/Multiplayer/VersusRow.cs @@ -0,0 +1,52 @@ +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Online.Multiplayer +{ + public class VersusRow : FillFlowContainer + { + public VersusRow(Color4 first, Color4 second, float size) + { + var triangleSize = new Vector2(size); + AutoSizeAxes = Axes.Both; + Spacing = new Vector2(2f, 0f); + + Children = new[] + { + new Container + { + Size = triangleSize, + Colour = first, + Children = new[] + { + new EquilateralTriangle + { + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + Rotation = 90, + EdgeSmoothness = new Vector2(1f), + }, + }, + }, + new Container + { + Size = triangleSize, + Colour = second, + Children = new[] + { + new EquilateralTriangle + { + Anchor = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + Rotation = -90, + EdgeSmoothness = new Vector2(1f), + }, + }, + }, + }; + } + } +} \ No newline at end of file diff --git a/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs b/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs index aec26a751e..caf686165f 100644 --- a/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs +++ b/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Online.Multiplayer; +using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Screens.Multi.Components; using osuTK; diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index eb7a206163..7892c335b6 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; +using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Match.Components; @@ -22,7 +23,7 @@ namespace osu.Game.Screens.Multi.Match public class MatchScreen : MultiplayerScreen { public override bool AllowBeatmapRulesetChange => false; - public override string Title => room.Name.Value; + public override string Title => room.RoomID.Value == null ? "New room" : room.Name.Value; public override string ShortTitle => "room"; private readonly RoomBindings bindings = new RoomBindings(); diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 7a8f9f3948..b9b86fbfc7 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -10,6 +10,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Screens.Menu; @@ -34,6 +35,9 @@ namespace osu.Game.Screens.Multi [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; + [Resolved] + private APIAccess api { get; set; } + public Multiplayer() { Child = waves = new MultiplayerWaveContainer @@ -82,13 +86,14 @@ namespace osu.Game.Screens.Multi Right = 10, }, Text = "Create room", - Action = () => loungeScreen.Open(new Room()) + Action = () => loungeScreen.Open(new Room + { + Name = { Value = $"{api.LocalUser}'s awesome room" } + }), }, roomManager = new RoomManager() }); - screenAdded(loungeScreen); - loungeScreen.Exited += s => Exit(); } From f442e5962059048fb929b993224b95bf5ef3f5f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 17:07:59 +0900 Subject: [PATCH 146/220] Icon and beatmap title visual pass --- .../Multiplayer/GameTypes/GameTypeTimeshift.cs | 3 +-- .../Multiplayer/{ => GameTypes}/VersusRow.cs | 2 +- osu.Game/Screens/Multi/Components/BeatmapTitle.cs | 15 +++++++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) rename osu.Game/Online/Multiplayer/{ => GameTypes}/VersusRow.cs (96%) diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs index e8aa82d022..e87f8a9696 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs @@ -13,10 +13,9 @@ namespace osu.Game.Online.Multiplayer.GameTypes Anchor = Anchor.Centre, Origin = Anchor.Centre, Icon = FontAwesome.fa_clock_o, - X = -2, // The icon is off-centre Size = new Vector2(size), Colour = colours.Blue, Shadow = false }; } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Multiplayer/VersusRow.cs b/osu.Game/Online/Multiplayer/GameTypes/VersusRow.cs similarity index 96% rename from osu.Game/Online/Multiplayer/VersusRow.cs rename to osu.Game/Online/Multiplayer/GameTypes/VersusRow.cs index 3c7ebd936e..2b150fc6f0 100644 --- a/osu.Game/Online/Multiplayer/VersusRow.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/VersusRow.cs @@ -4,7 +4,7 @@ using osu.Framework.Graphics.Shapes; using osuTK; using osuTK.Graphics; -namespace osu.Game.Online.Multiplayer +namespace osu.Game.Online.Multiplayer.GameTypes { public class VersusRow : FillFlowContainer { diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index d609f7a70d..b58af398ca 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs @@ -1,11 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; using osu.Game.Beatmaps; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.Chat; @@ -23,14 +25,12 @@ namespace osu.Game.Screens.Multi.Components AutoSizeAxes = Axes.Both; InternalChild = textFlow = new LinkFlowContainer { AutoSizeAxes = Axes.Both }; - - Beatmap.BindValueChanged(v => updateText()); } protected override void LoadComplete() { base.LoadComplete(); - updateText(); + Beatmap.BindValueChanged(v => updateText(), true); } private float textSize = OsuSpriteText.FONT_SIZE; @@ -48,6 +48,9 @@ namespace osu.Game.Screens.Multi.Components } } + [Resolved] + private OsuColour colours { get; set; } + private void updateText() { if (!IsLoaded) @@ -56,7 +59,11 @@ namespace osu.Game.Screens.Multi.Components textFlow.Clear(); if (Beatmap.Value == null) - textFlow.AddText("Changing map", s => s.TextSize = TextSize); + textFlow.AddText("No beatmap selected", s => + { + s.TextSize = TextSize; + s.Colour = colours.PinkLight; + }); else { textFlow.AddLink(new[] From 63847890d15e64be77da4e4ecf9329711d8e392f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 18:05:12 +0900 Subject: [PATCH 147/220] Add better messaging when connecting or failing --- .../Graphics/Containers/LinkFlowContainer.cs | 21 ++++++++++++-- .../Sections/General/LoginSettings.cs | 29 +++++++++++-------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 54a2ea47f9..74315d2522 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; using System.Collections.Generic; +using osu.Framework.Graphics; using osu.Framework.Logging; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; @@ -61,11 +62,25 @@ namespace osu.Game.Graphics.Containers } public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action creationParameters = null) + => createLink(AddText(text, creationParameters), text, url, linkType, linkArgument, tooltipText); + + public void AddLink(string text, Action action, string tooltipText = null, Action creationParameters = null) + => createLink(AddText(text, creationParameters), text, tooltipText: tooltipText, action: action); + + public void AddLink(IEnumerable text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null) { - AddInternal(new DrawableLinkCompiler(AddText(text, creationParameters).ToList()) + foreach (var t in text) + AddArbitraryDrawable(t); + + createLink(text, null, url, linkType, linkArgument, tooltipText); + } + + private void createLink(IEnumerable drawables, string text, string url = null, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action action = null) + { + AddInternal(new DrawableLinkCompiler(drawables.OfType().ToList()) { TooltipText = tooltipText ?? (url != text ? url : string.Empty), - Action = () => + Action = action ?? (() => { switch (linkType) { @@ -104,7 +119,7 @@ namespace osu.Game.Graphics.Containers default: throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action."); } - }, + }), }); } } diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 0cb6d2d1aa..163eced103 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -17,6 +17,7 @@ using osu.Game.Graphics; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; using RectangleF = osu.Framework.Graphics.Primitives.RectangleF; using Container = osu.Framework.Graphics.Containers.Container; @@ -86,25 +87,29 @@ namespace osu.Game.Overlays.Settings.Sections.General }; break; case APIState.Failing: - Children = new Drawable[] - { - new OsuSpriteText - { - Text = "Connection failing :(", - }, - }; - break; case APIState.Connecting: + LinkFlowContainer linkFlow; + Children = new Drawable[] { - new OsuSpriteText + new LoadingAnimation { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Text = "Connecting...", + State = Visibility.Visible, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }, + linkFlow = new LinkFlowContainer + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + TextAnchor = Anchor.TopCentre, + AutoSizeAxes = Axes.Both, + Text = state == APIState.Failing ? "Connection is failing, will attempt to reconnect... " : "Attempting to connect... ", Margin = new MarginPadding { Top = 10, Bottom = 10 }, }, }; + + linkFlow.AddLink("cancel", api.Logout, string.Empty); break; case APIState.Online: Children = new Drawable[] From edfb027ff274fc50c67c3d9204bfd3ce4067abf3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 18:49:33 +0900 Subject: [PATCH 148/220] Update framework --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 18addaefb6..103c7c20d6 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From 0cefd4b21dc299309bda76968f3f3d7e4cfbfe25 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 19:14:15 +0900 Subject: [PATCH 149/220] Improve room padding --- osu.Game/Screens/Multi/Lounge/LoungeScreen.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs index 82d593033f..cb8591be9e 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs @@ -47,11 +47,8 @@ namespace osu.Game.Screens.Multi.Lounge { RelativeSizeAxes = Axes.Both, Width = 0.55f, - Padding = new MarginPadding - { - Vertical = 35 - DrawableRoom.SELECTION_BORDER_WIDTH, - Right = 20 - DrawableRoom.SELECTION_BORDER_WIDTH - }, + ScrollbarOverlapsContent = false, + Padding = new MarginPadding(10), Child = new SearchContainer { RelativeSizeAxes = Axes.X, @@ -140,7 +137,7 @@ namespace osu.Game.Screens.Multi.Lounge if (!IsCurrentScreen) return; - Push(new MatchScreen(room, s => pushGameplayScreen?.Invoke(s))); + Push(new MatchScreen(room, s => pushGameplayScreen?.Invoke(s))); } protected override void Dispose(bool isDisposing) From 532a970c0fbcd20584b70c5e00c4edeca8db8775 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 19:20:54 +0900 Subject: [PATCH 150/220] Give leaderboard and chat more breathing room --- osu.Game/Screens/Multi/Match/MatchScreen.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index 7892c335b6..c784a27b99 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -73,8 +73,20 @@ namespace osu.Game.Screens.Multi.Match { new Drawable[] { - leaderboard = new MatchLeaderboard(room) { RelativeSizeAxes = Axes.Both }, - chat = new MatchChatDisplay(room) { RelativeSizeAxes = Axes.Both } + leaderboard = new MatchLeaderboard(room) + { + Padding = new MarginPadding(10), + RelativeSizeAxes = Axes.Both + }, + new Container + { + Padding = new MarginPadding(10), + RelativeSizeAxes = Axes.Both, + Child = chat = new MatchChatDisplay(room) + { + RelativeSizeAxes = Axes.Both + } + }, }, }, } From 2353c204ee502365a6684949c53887ae321c95d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 20:05:57 +0900 Subject: [PATCH 151/220] Renaming --- .../Visual/TestCaseLoungeRoomsContainer.cs | 4 +-- .../Visual/TestCaseMatchSettingsOverlay.cs | 2 +- osu.Game.Tests/Visual/TestCaseMultiHeader.cs | 8 +++--- osu.Game.Tests/Visual/TestCaseMultiResults.cs | 10 +++---- osu.Game.Tests/Visual/TestCaseMultiScreen.cs | 2 +- osu.Game/Screens/Multi/Header.cs | 2 +- ...ayerScreen.cs => IMultiplayerSubScreen.cs} | 2 +- osu.Game/Screens/Multi/IRoomManager.cs | 4 +-- .../{LoungeScreen.cs => LoungeSubScreen.cs} | 13 +++++----- .../{MatchScreen.cs => MatchSubScreen.cs} | 10 +++++-- osu.Game/Screens/Multi/Multiplayer.cs | 26 +++++++++++-------- ...layerScreen.cs => MultiplayerSubScreen.cs} | 2 +- .../Screens/Multi/Play/TimeshiftPlayer.cs | 2 +- .../{MultiResults.cs => MatchResults.cs} | 4 +-- osu.Game/Screens/Multi/RoomManager.cs | 4 +-- osu.Game/Screens/Select/MatchSongSelect.cs | 2 +- 16 files changed, 54 insertions(+), 43 deletions(-) rename osu.Game/Screens/Multi/{IMultiplayerScreen.cs => IMultiplayerSubScreen.cs} (84%) rename osu.Game/Screens/Multi/Lounge/{LoungeScreen.cs => LoungeSubScreen.cs} (92%) rename osu.Game/Screens/Multi/Match/{MatchScreen.cs => MatchSubScreen.cs} (95%) rename osu.Game/Screens/Multi/{MultiplayerScreen.cs => MultiplayerSubScreen.cs} (95%) rename osu.Game/Screens/Multi/Ranking/{MultiResults.cs => MatchResults.cs} (89%) diff --git a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs index 916468ae2f..dd7e8f7fac 100644 --- a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs @@ -71,14 +71,14 @@ namespace osu.Game.Tests.Visual private class TestRoomManager : IRoomManager { - public event Action OpenRequested; + public event Action RoomJoined; public readonly BindableCollection Rooms = new BindableCollection(); IBindableCollection IRoomManager.Rooms => Rooms; public void CreateRoom(Room room) => Rooms.Add(room); - public void JoinRoom(Room room) => OpenRequested?.Invoke(room); + public void JoinRoom(Room room) => RoomJoined?.Invoke(room); public void PartRoom() { diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index 322ff5bc07..3c41fd6920 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual { public Action CreateRequested; - public event Action OpenRequested; + public event Action RoomJoined; public IBindableCollection Rooms { get; } = null; diff --git a/osu.Game.Tests/Visual/TestCaseMultiHeader.cs b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs index 2005c707b1..602108d078 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiHeader.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs @@ -15,7 +15,7 @@ namespace osu.Game.Tests.Visual { int index = 0; - OsuScreen currentScreen = new TestMultiplayerScreen(index); + OsuScreen currentScreen = new TestMultiplayerSubScreen(index); Children = new Drawable[] { @@ -23,16 +23,16 @@ namespace osu.Game.Tests.Visual new Header(currentScreen) }; - AddStep("push multi screen", () => currentScreen.Push(currentScreen = new TestMultiplayerScreen(++index))); + AddStep("push multi screen", () => currentScreen.Push(currentScreen = new TestMultiplayerSubScreen(++index))); } - private class TestMultiplayerScreen : OsuScreen, IMultiplayerScreen + private class TestMultiplayerSubScreen : OsuScreen, IMultiplayerSubScreen { private readonly int index; public string ShortTitle => $"Screen {index}"; - public TestMultiplayerScreen(int index) + public TestMultiplayerSubScreen(int index) { this.index = index; } diff --git a/osu.Game.Tests/Visual/TestCaseMultiResults.cs b/osu.Game.Tests/Visual/TestCaseMultiResults.cs index 38027e0bc3..8991782835 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiResults.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiResults.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { - typeof(MultiResults), + typeof(MatchResults), typeof(RoomLeaderboardPageInfo), typeof(RoomRankingResultsPage) }; @@ -38,22 +38,22 @@ namespace osu.Game.Tests.Visual if (beatmapInfo != null) Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo); - Child = new TestMultiResults(new ScoreInfo + Child = new TestMatchResults(new ScoreInfo { User = new User { Id = 10 }, }); } - private class TestMultiResults : MultiResults + private class TestMatchResults : MatchResults { private readonly Room room; - public TestMultiResults(ScoreInfo score) + public TestMatchResults(ScoreInfo score) : this(score, new Room()) { } - public TestMultiResults(ScoreInfo score, Room room) + public TestMatchResults(ScoreInfo score, Room room) : base(score, room) { this.room = room; diff --git a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs index c65ab4e3e3..88265d146f 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(Multiplayer), - typeof(LoungeScreen), + typeof(LoungeSubScreen), typeof(FilterControl) }; diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 849be44f4f..2849fd89e0 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -87,7 +87,7 @@ namespace osu.Game.Screens.Multi breadcrumbs.Current.ValueChanged += s => { - if (s is IMultiplayerScreen mpScreen) + if (s is IMultiplayerSubScreen mpScreen) screenType.Text = mpScreen.ShortTitle.ToLowerInvariant(); }; diff --git a/osu.Game/Screens/Multi/IMultiplayerScreen.cs b/osu.Game/Screens/Multi/IMultiplayerSubScreen.cs similarity index 84% rename from osu.Game/Screens/Multi/IMultiplayerScreen.cs rename to osu.Game/Screens/Multi/IMultiplayerSubScreen.cs index c1f43fa30d..4796ffc05c 100644 --- a/osu.Game/Screens/Multi/IMultiplayerScreen.cs +++ b/osu.Game/Screens/Multi/IMultiplayerSubScreen.cs @@ -3,7 +3,7 @@ namespace osu.Game.Screens.Multi { - public interface IMultiplayerScreen + public interface IMultiplayerSubScreen { string ShortTitle { get; } } diff --git a/osu.Game/Screens/Multi/IRoomManager.cs b/osu.Game/Screens/Multi/IRoomManager.cs index f09f360ea2..b94df93581 100644 --- a/osu.Game/Screens/Multi/IRoomManager.cs +++ b/osu.Game/Screens/Multi/IRoomManager.cs @@ -11,9 +11,9 @@ namespace osu.Game.Screens.Multi public interface IRoomManager { /// - /// Invoked when this requests a to be opened. + /// Invoked when a room is joined. /// - event Action OpenRequested; + event Action RoomJoined; /// /// All the active s. diff --git a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs similarity index 92% rename from osu.Game/Screens/Multi/Lounge/LoungeScreen.cs rename to osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index cb8591be9e..c49cfc6b9c 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Multi.Match; namespace osu.Game.Screens.Multi.Lounge { - public class LoungeScreen : MultiplayerScreen + public class LoungeSubScreen : MultiplayerSubScreen { protected readonly FilterControl Filter; @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Multi.Lounge protected override Drawable TransitionContent => content; - public LoungeScreen(Action pushGameplayScreen) + public LoungeSubScreen(Action pushGameplayScreen) { this.pushGameplayScreen = pushGameplayScreen; @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Multi.Lounge private void load() { if (roomManager != null) - roomManager.OpenRequested += Open; + roomManager.RoomJoined += Open; } protected override void UpdateAfterChildren() @@ -109,7 +109,8 @@ namespace osu.Game.Screens.Multi.Lounge roomManager?.PartRoom(); Filter.Search.HoldFocus = false; - return base.OnExiting(next); + // no base call; don't animate + return false; } protected override void OnResuming(Screen last) @@ -137,7 +138,7 @@ namespace osu.Game.Screens.Multi.Lounge if (!IsCurrentScreen) return; - Push(new MatchScreen(room, s => pushGameplayScreen?.Invoke(s))); + Push(new MatchSubScreen(room, s => pushGameplayScreen?.Invoke(s))); } protected override void Dispose(bool isDisposing) @@ -145,7 +146,7 @@ namespace osu.Game.Screens.Multi.Lounge base.Dispose(isDisposing); if (roomManager != null) - roomManager.OpenRequested -= Open; + roomManager.RoomJoined -= Open; } } } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs similarity index 95% rename from osu.Game/Screens/Multi/Match/MatchScreen.cs rename to osu.Game/Screens/Multi/Match/MatchSubScreen.cs index c784a27b99..982f54f7c8 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -20,7 +20,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Screens.Multi.Match { - public class MatchScreen : MultiplayerScreen + public class MatchSubScreen : MultiplayerSubScreen { public override bool AllowBeatmapRulesetChange => false; public override string Title => room.RoomID.Value == null ? "New room" : room.Name.Value; @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Multi.Match [Resolved(CanBeNull = true)] private IRoomManager manager { get; set; } - public MatchScreen(Room room, Action pushGameplayScreen) + public MatchSubScreen(Room room, Action pushGameplayScreen) { this.room = room; this.pushGameplayScreen = pushGameplayScreen; @@ -119,6 +119,12 @@ namespace osu.Game.Screens.Multi.Match chat.Exit += Exit; } + protected override bool OnExiting(Screen next) + { + manager?.PartRoom(); + return base.OnExiting(next); + } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index b9b86fbfc7..b105024a24 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Multi public override bool AllowBeatmapRulesetChange => currentScreen?.AllowBeatmapRulesetChange ?? base.AllowBeatmapRulesetChange; private readonly OsuButton createButton; - private readonly LoungeScreen loungeScreen; + private readonly LoungeSubScreen loungeSubScreen; private OsuScreen currentScreen; @@ -71,9 +71,9 @@ namespace osu.Game.Screens.Multi { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Header.HEIGHT }, - Child = loungeScreen = new LoungeScreen(Push), + Child = loungeSubScreen = new LoungeSubScreen(Push), }, - new Header(loungeScreen), + new Header(loungeSubScreen), createButton = new HeaderButton { Anchor = Anchor.TopRight, @@ -86,19 +86,22 @@ namespace osu.Game.Screens.Multi Right = 10, }, Text = "Create room", - Action = () => loungeScreen.Open(new Room + Action = () => loungeSubScreen.Open(new Room { Name = { Value = $"{api.LocalUser}'s awesome room" } }), }, roomManager = new RoomManager() }); - screenAdded(loungeScreen); - loungeScreen.Exited += s => Exit(); + + screenAdded(loungeSubScreen); + loungeSubScreen.Exited += _ => Exit(); } protected override void OnEntering(Screen last) { + Content.FadeIn(); + base.OnEntering(last); waves.Show(); } @@ -107,12 +110,13 @@ namespace osu.Game.Screens.Multi { waves.Hide(); + Content.Delay(WaveContainer.DISAPPEAR_DURATION).FadeOut(); + var track = Beatmap.Value.Track; if (track != null) track.Looping = false; - loungeScreen.MakeCurrent(); - loungeScreen.Exit(); + loungeSubScreen.MakeCurrent(); return base.OnExiting(next); } @@ -144,7 +148,7 @@ namespace osu.Game.Screens.Multi { base.Update(); - if (currentScreen is MatchScreen) + if (currentScreen is MatchSubScreen) { var track = Beatmap.Value.Track; if (track != null) @@ -161,7 +165,7 @@ namespace osu.Game.Screens.Multi createButton.Hide(); } - else if (currentScreen is LoungeScreen) + else if (currentScreen is LoungeSubScreen) createButton.Show(); } @@ -175,7 +179,7 @@ namespace osu.Game.Screens.Multi private void screenRemoved(Screen newScreen) { - if (currentScreen is MatchScreen) + if (currentScreen is MatchSubScreen) { var track = Beatmap.Value.Track; if (track != null) diff --git a/osu.Game/Screens/Multi/MultiplayerScreen.cs b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs similarity index 95% rename from osu.Game/Screens/Multi/MultiplayerScreen.cs rename to osu.Game/Screens/Multi/MultiplayerSubScreen.cs index da9a2b3051..5a7eaafba5 100644 --- a/osu.Game/Screens/Multi/MultiplayerScreen.cs +++ b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs @@ -7,7 +7,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Multi { - public abstract class MultiplayerScreen : OsuScreen, IMultiplayerScreen + public abstract class MultiplayerSubScreen : OsuScreen, IMultiplayerSubScreen { protected virtual Drawable TransitionContent => Content; diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index f33159f69b..0a7c11ecc5 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -72,6 +72,6 @@ namespace osu.Game.Screens.Multi.Play return score; } - protected override Results CreateResults(ScoreInfo score) => new MultiResults(score, room); + protected override Results CreateResults(ScoreInfo score) => new MatchResults(score, room); } } diff --git a/osu.Game/Screens/Multi/Ranking/MultiResults.cs b/osu.Game/Screens/Multi/Ranking/MatchResults.cs similarity index 89% rename from osu.Game/Screens/Multi/Ranking/MultiResults.cs rename to osu.Game/Screens/Multi/Ranking/MatchResults.cs index 0fffe250bf..c0544540c4 100644 --- a/osu.Game/Screens/Multi/Ranking/MultiResults.cs +++ b/osu.Game/Screens/Multi/Ranking/MatchResults.cs @@ -10,11 +10,11 @@ using osu.Game.Screens.Ranking.Types; namespace osu.Game.Screens.Multi.Ranking { - public class MultiResults : Results + public class MatchResults : Results { private readonly Room room; - public MultiResults(ScoreInfo score, Room room) + public MatchResults(ScoreInfo score, Room room) : base(score) { this.room = room; diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 4bd9307bfb..68a11c0ba8 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Multi { public class RoomManager : PollingComponent, IRoomManager { - public event Action OpenRequested; + public event Action RoomJoined; private readonly BindableCollection rooms = new BindableCollection(); public IBindableCollection Rooms => rooms; @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Multi currentJoinRoomRequest.Success += () => { currentRoom = room; - OpenRequested?.Invoke(room); + RoomJoined?.Invoke(room); }; currentJoinRoomRequest.Failure += exception => Logger.Log($"Failed to join room: {exception}"); diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index f5ce34ea25..5763b84e89 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -8,7 +8,7 @@ using osu.Game.Screens.Multi; namespace osu.Game.Screens.Select { - public class MatchSongSelect : SongSelect, IMultiplayerScreen + public class MatchSongSelect : SongSelect, IMultiplayerSubScreen { public Action Selected; From 692f5c289d363b0d1fa227675b634f24fb55fbdf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 20:12:51 +0900 Subject: [PATCH 152/220] Move PartRoom calls --- osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs | 9 --------- osu.Game/Screens/Multi/RoomManager.cs | 6 ++++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index c49cfc6b9c..7ec04087de 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -106,20 +106,11 @@ namespace osu.Game.Screens.Multi.Lounge protected override bool OnExiting(Screen next) { - roomManager?.PartRoom(); - Filter.Search.HoldFocus = false; // no base call; don't animate return false; } - protected override void OnResuming(Screen last) - { - roomManager?.PartRoom(); - - base.OnResuming(last); - } - protected override void OnSuspending(Screen next) { base.OnSuspending(next); diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 68a11c0ba8..0af96c2e1b 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -42,6 +42,12 @@ namespace osu.Game.Screens.Multi TimeBetweenPolls = 5000; } + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + PartRoom(); + } + public void CreateRoom(Room room) { room.Host.Value = api.LocalUser; From 869081ce9cbe99c5c89c842009ac8de6b88252b9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 20:21:30 +0900 Subject: [PATCH 153/220] Open -> Push --- osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs | 9 ++++++--- osu.Game/Screens/Multi/Multiplayer.cs | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index 7ec04087de..aef8265130 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Multi.Lounge private void load() { if (roomManager != null) - roomManager.RoomJoined += Open; + roomManager.RoomJoined += Push; } protected override void UpdateAfterChildren() @@ -123,7 +123,10 @@ namespace osu.Game.Screens.Multi.Lounge roomManager?.Filter(Filter.CreateCriteria()); } - public void Open(Room room) + /// + /// Push a room as a new subscreen. + /// + public void Push(Room room) { // Handles the case where a room is clicked 3 times in quick succession if (!IsCurrentScreen) @@ -137,7 +140,7 @@ namespace osu.Game.Screens.Multi.Lounge base.Dispose(isDisposing); if (roomManager != null) - roomManager.RoomJoined -= Open; + roomManager.RoomJoined -= Push; } } } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index b105024a24..40f66811f7 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Multi Right = 10, }, Text = "Create room", - Action = () => loungeSubScreen.Open(new Room + Action = () => loungeSubScreen.Push(new Room { Name = { Value = $"{api.LocalUser}'s awesome room" } }), From 7a431ed87f322320eacda6fc73023ea223701fe8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 20:31:04 +0900 Subject: [PATCH 154/220] Update ParticipantInfo --- .../Lounge/Components/ParticipantInfo.cs | 47 ++++--------------- .../Multi/Lounge/Components/RoomInspector.cs | 2 +- 2 files changed, 11 insertions(+), 38 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs index b0ce800d4b..1bc6d5aec0 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs @@ -2,12 +2,10 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -19,12 +17,12 @@ namespace osu.Game.Screens.Multi.Lounge.Components { public class ParticipantInfo : Container { - private readonly FillFlowContainer levelRangeContainer; + private readonly FillFlowContainer summaryContainer; public readonly IBindable Host = new Bindable(); public readonly IBindable> Participants = new Bindable>(); - public ParticipantInfo(string rankPrefix = null) + public ParticipantInfo() { RelativeSizeAxes = Axes.X; Height = 15f; @@ -49,7 +47,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Width = 22f, RelativeSizeAxes = Axes.Y, }, - new Container //todo: team banners + /*new Container //todo: team banners { Width = 38f, RelativeSizeAxes = Axes.Y, @@ -63,7 +61,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Colour = OsuColour.FromHex(@"ad387e"), }, }, - }, + },*/ hostText = new LinkFlowContainer { Anchor = Anchor.CentreLeft, @@ -72,7 +70,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components } }, }, - levelRangeContainer = new FillFlowContainer + summaryContainer = new FillFlowContainer { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -82,34 +80,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components { new OsuSpriteText { - Text = rankPrefix, + Text = "0 participants", TextSize = 14, - }, - new OsuSpriteText - { - Text = "#", - TextSize = 14, - }, - levelRangeLower = new OsuSpriteText - { - TextSize = 14, - Font = @"Exo2.0-Bold", - }, - new OsuSpriteText - { - Text = " - ", - TextSize = 14, - }, - new OsuSpriteText - { - Text = "#", - TextSize = 14, - }, - levelRangeHigher = new OsuSpriteText - { - TextSize = 14, - Font = @"Exo2.0-Bold", - }, + } }, }, }; @@ -123,18 +96,18 @@ namespace osu.Game.Screens.Multi.Lounge.Components flagContainer.Child = new DrawableFlag(v.Country) { RelativeSizeAxes = Axes.Both }; }); - Participants.BindValueChanged(v => + /*Participants.BindValueChanged(v => { var ranks = v.Select(u => u.Statistics.Ranks.Global); levelRangeLower.Text = ranks.Min().ToString(); levelRangeHigher.Text = ranks.Max().ToString(); - }); + });*/ } [BackgroundDependencyLoader] private void load(OsuColour colours) { - levelRangeContainer.Colour = colours.Gray9; + summaryContainer.Colour = colours.Gray9; } } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 08beace4ca..be16d89255 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -142,7 +142,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Padding = contentPadding, Children = new Drawable[] { - participantInfo = new ParticipantInfo(@"Rank Range "), + participantInfo = new ParticipantInfo(), }, }, }, From 052ab4763acf49971326cc47ef6e0062bd0b6896 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 17:44:36 +0900 Subject: [PATCH 155/220] Display room join errors as notifications --- osu.Game/Screens/Multi/RoomManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 68a11c0ba8..2aefc4f558 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -67,7 +67,7 @@ namespace osu.Game.Screens.Multi RoomJoined?.Invoke(room); }; - currentJoinRoomRequest.Failure += exception => Logger.Log($"Failed to join room: {exception}"); + currentJoinRoomRequest.Failure += exception => Logger.Log($"Failed to join room: {exception}", level: LogLevel.Important); api.Queue(currentJoinRoomRequest); } From be9ba78d47a014532b1fba6e97ae3e11dc1164c0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 18:38:58 +0900 Subject: [PATCH 156/220] Add error message when creation fails --- .../Visual/TestCaseLoungeRoomsContainer.cs | 2 +- .../Visual/TestCaseMatchSettingsOverlay.cs | 49 +++++++++++++++++-- .../Online/API/Requests/CreateRoomRequest.cs | 3 +- .../API/Requests/Responses/APICreatedRoom.cs | 14 ++++++ osu.Game/Screens/Multi/IRoomManager.cs | 3 +- .../Match/Components/MatchSettingsOverlay.cs | 44 ++++++++++++++--- osu.Game/Screens/Multi/RoomManager.cs | 10 +++- 7 files changed, 109 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs diff --git a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs index dd7e8f7fac..e42781849d 100644 --- a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs @@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual public readonly BindableCollection Rooms = new BindableCollection(); IBindableCollection IRoomManager.Rooms => Rooms; - public void CreateRoom(Room room) => Rooms.Add(room); + public void CreateRoom(Room room, Action onError = null) => Rooms.Add(room); public void JoinRoom(Room room) => RoomJoined?.Invoke(room); diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index 3c41fd6920..a31b91cc2a 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -9,6 +9,7 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi; @@ -77,7 +78,11 @@ namespace osu.Game.Tests.Visual settings.NameField.Current.Value = expected_name; settings.DurationField.Current.Value = expectedDuration; - roomManager.CreateRequested = r => createdRoom = r; + roomManager.CreateRequested = r => + { + createdRoom = r; + return true; + }; }); AddStep("create room", () => settings.ApplyButton.Action.Invoke()); @@ -85,13 +90,40 @@ namespace osu.Game.Tests.Visual AddAssert("has correct duration", () => createdRoom.Duration.Value == expectedDuration); } - private class TestRoomSettings : MatchSettingsOverlay + [Test] + public void TestCreationFailureDisplaysError() + { + bool fail; + + AddStep("setup", () => + { + fail = true; + roomManager.CreateRequested = _ => !fail; + }); + AddAssert("error not displayed", () => !settings.ErrorText.IsPresent); + + AddStep("create room", () => settings.ApplyButton.Action.Invoke()); + AddAssert("error displayed", () => settings.ErrorText.IsPresent); + AddAssert("error has correct text", () => settings.ErrorText.Text == TestRoomManager.FAILED_TEXT); + + AddStep("create room no fail", () => + { + fail = false; + settings.ApplyButton.Action.Invoke(); + }); + + AddUntilStep(() => !settings.ErrorText.IsPresent, "error not displayed"); + } + + private class TestRoomSettings : RoomSettingsOverlay { public new TriangleButton ApplyButton => base.ApplyButton; public new OsuTextBox NameField => base.NameField; public new OsuDropdown DurationField => base.DurationField; + public new OsuSpriteText ErrorText => base.ErrorText; + public TestRoomSettings(Room room) : base(room) { @@ -100,13 +132,22 @@ namespace osu.Game.Tests.Visual private class TestRoomManager : IRoomManager { - public Action CreateRequested; + public const string FAILED_TEXT = "failed"; + + public Func CreateRequested; public event Action RoomJoined; public IBindableCollection Rooms { get; } = null; - public void CreateRoom(Room room) => CreateRequested?.Invoke(room); + public void CreateRoom(Room room, Action onError = null) + { + if (CreateRequested == null) + return; + + if (!CreateRequested.Invoke(room)) + onError?.Invoke(FAILED_TEXT); + } public void JoinRoom(Room room) => throw new NotImplementedException(); diff --git a/osu.Game/Online/API/Requests/CreateRoomRequest.cs b/osu.Game/Online/API/Requests/CreateRoomRequest.cs index 7ce289b65a..fc401be5f1 100644 --- a/osu.Game/Online/API/Requests/CreateRoomRequest.cs +++ b/osu.Game/Online/API/Requests/CreateRoomRequest.cs @@ -4,11 +4,12 @@ using System.Net.Http; using Newtonsoft.Json; using osu.Framework.IO.Network; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Multiplayer; namespace osu.Game.Online.API.Requests { - public class CreateRoomRequest : APIRequest + public class CreateRoomRequest : APIRequest { private readonly Room room; diff --git a/osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs b/osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs new file mode 100644 index 0000000000..ca0daa04b6 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; +using osu.Game.Online.Multiplayer; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APICreatedRoom : Room + { + [JsonProperty("error")] + public string Error { get; set; } + } +} diff --git a/osu.Game/Screens/Multi/IRoomManager.cs b/osu.Game/Screens/Multi/IRoomManager.cs index b94df93581..bb996f0b5c 100644 --- a/osu.Game/Screens/Multi/IRoomManager.cs +++ b/osu.Game/Screens/Multi/IRoomManager.cs @@ -24,7 +24,8 @@ namespace osu.Game.Screens.Multi /// Creates a new . /// /// The to create. - void CreateRoom(Room room); + /// An action to be invoked if an error occurred. + void CreateRoom(Room room, Action onError = null); /// /// Joins a . diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 6de2bed938..d6228b106b 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -37,6 +37,8 @@ namespace osu.Game.Screens.Multi.Match.Components protected readonly TriangleButton ApplyButton; protected readonly OsuPasswordTextBox PasswordField; + protected readonly OsuSpriteText ErrorText; + private readonly Room room; [Resolved(CanBeNull = true)] @@ -200,14 +202,31 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex(@"28242d").Darken(0.5f).Opacity(1f), }, - ApplyButton = new CreateRoomButton + new FillFlowContainer { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), Margin = new MarginPadding { Vertical = 20 }, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(230, 55), - Action = apply, - }, + Children = new Drawable[] + { + ApplyButton = new CreateRoomButton + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(230, 55), + Action = apply, + }, + ErrorText = new OsuSpriteText + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Alpha = 0, + Depth = 1 + } + } + } } } } @@ -229,6 +248,7 @@ namespace osu.Game.Screens.Multi.Match.Components private void load(OsuColour colours) { typeLabel.Colour = colours.Yellow; + ErrorText.Colour = colours.RedDark; MaxParticipantsField.ReadOnly = true; PasswordField.ReadOnly = true; @@ -258,6 +278,8 @@ namespace osu.Game.Screens.Multi.Match.Components private void apply() { + hideError(); + bindings.Name.Value = NameField.Text; bindings.Availability.Value = AvailabilityPicker.Current.Value; bindings.Type.Value = TypePicker.Current.Value; @@ -269,7 +291,15 @@ namespace osu.Game.Screens.Multi.Match.Components bindings.Duration.Value = DurationField.Current.Value; - manager?.CreateRoom(room); + manager?.CreateRoom(room, showError); + } + + private void hideError() => ErrorText.FadeOut(50); + + private void showError(string text) + { + ErrorText.Text = text; + ErrorText.FadeIn(50); } private class SettingsTextBox : OsuTextBox diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 2aefc4f558..c5345e5453 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -42,13 +42,19 @@ namespace osu.Game.Screens.Multi TimeBetweenPolls = 5000; } - public void CreateRoom(Room room) + public void CreateRoom(Room room, Action onError = null) { room.Host.Value = api.LocalUser; var req = new CreateRoomRequest(room); req.Success += result => addRoom(room, result); - req.Failure += exception => Logger.Log($"Failed to create room: {exception}"); + req.Failure += exception => + { + if (req.Result != null) + onError?.Invoke(req.Result.Error); + else + Logger.Log($"Failed to create the room: {exception}", level: LogLevel.Important); + }; api.Queue(req); } From 9d305ba0247bb2444ad74878d5b9eb8574a37e91 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 20:32:01 +0900 Subject: [PATCH 157/220] Reduce code duplication --- osu.Game/Screens/Multi/RoomManager.cs | 45 ++++++++++++++++----------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index c5345e5453..54d35db1c7 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -47,7 +47,12 @@ namespace osu.Game.Screens.Multi room.Host.Value = api.LocalUser; var req = new CreateRoomRequest(room); - req.Success += result => addRoom(room, result); + req.Success += result => + { + update(room, result); + addRoom(room); + }; + req.Failure += exception => { if (req.Result != null) @@ -114,13 +119,8 @@ namespace osu.Game.Screens.Multi // Add new matches, or update existing foreach (var r in result) { - processPlaylist(r); - - var existing = rooms.FirstOrDefault(e => e.RoomID.Value == r.RoomID.Value); - if (existing == null) - rooms.Add(r); - else - existing.CopyFrom(r); + update(r, r); + addRoom(r); } tcs.SetResult(true); @@ -133,22 +133,29 @@ namespace osu.Game.Screens.Multi return tcs.Task; } - private void addRoom(Room local, Room remote) + /// + /// Updates a local with a remote copy. + /// + /// The local to update. + /// The remote to update with. + private void update(Room local, Room remote) { - processPlaylist(remote); - + foreach (var pi in remote.Playlist) + pi.MapObjects(beatmaps, rulesets); local.CopyFrom(remote); - - var existing = rooms.FirstOrDefault(e => e.RoomID.Value == local.RoomID.Value); - if (existing != null) - rooms.Remove(existing); - rooms.Add(local); } - private void processPlaylist(Room room) + /// + /// Adds a to the list of available rooms. + /// + /// The to add.< + private void addRoom(Room room) { - foreach (var pi in room.Playlist) - pi.MapObjects(beatmaps, rulesets); + var existing = rooms.FirstOrDefault(e => e.RoomID.Value == room.RoomID.Value); + if (existing == null) + rooms.Add(room); + else + existing.CopyFrom(room); } } } From 23d412e3ff7720f6a8cc38dddfe6a6db4734bbbd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 20:33:49 +0900 Subject: [PATCH 158/220] Fix post-rebase errors --- osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index a31b91cc2a..f93d1b3069 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual AddUntilStep(() => !settings.ErrorText.IsPresent, "error not displayed"); } - private class TestRoomSettings : RoomSettingsOverlay + private class TestRoomSettings : MatchSettingsOverlay { public new TriangleButton ApplyButton => base.ApplyButton; From 6f0d13e36b240db366cb4d6d4b454e79519250ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 20:12:51 +0900 Subject: [PATCH 159/220] Move PartRoom calls --- osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs | 9 --------- osu.Game/Screens/Multi/RoomManager.cs | 6 ++++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index c49cfc6b9c..7ec04087de 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -106,20 +106,11 @@ namespace osu.Game.Screens.Multi.Lounge protected override bool OnExiting(Screen next) { - roomManager?.PartRoom(); - Filter.Search.HoldFocus = false; // no base call; don't animate return false; } - protected override void OnResuming(Screen last) - { - roomManager?.PartRoom(); - - base.OnResuming(last); - } - protected override void OnSuspending(Screen next) { base.OnSuspending(next); diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 54d35db1c7..d91c05f79f 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -42,6 +42,12 @@ namespace osu.Game.Screens.Multi TimeBetweenPolls = 5000; } + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + PartRoom(); + } + public void CreateRoom(Room room, Action onError = null) { room.Host.Value = api.LocalUser; From 5bd3ab51ddd55755019760437c6baea5ae918cab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 20:21:30 +0900 Subject: [PATCH 160/220] Open -> Push --- osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs | 9 ++++++--- osu.Game/Screens/Multi/Multiplayer.cs | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index 7ec04087de..aef8265130 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Multi.Lounge private void load() { if (roomManager != null) - roomManager.RoomJoined += Open; + roomManager.RoomJoined += Push; } protected override void UpdateAfterChildren() @@ -123,7 +123,10 @@ namespace osu.Game.Screens.Multi.Lounge roomManager?.Filter(Filter.CreateCriteria()); } - public void Open(Room room) + /// + /// Push a room as a new subscreen. + /// + public void Push(Room room) { // Handles the case where a room is clicked 3 times in quick succession if (!IsCurrentScreen) @@ -137,7 +140,7 @@ namespace osu.Game.Screens.Multi.Lounge base.Dispose(isDisposing); if (roomManager != null) - roomManager.RoomJoined -= Open; + roomManager.RoomJoined -= Push; } } } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index b105024a24..40f66811f7 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Multi Right = 10, }, Text = "Create room", - Action = () => loungeSubScreen.Open(new Room + Action = () => loungeSubScreen.Push(new Room { Name = { Value = $"{api.LocalUser}'s awesome room" } }), From 8386e206c3347ac893e9b0f05f16ff4b0ee350f0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 20:31:04 +0900 Subject: [PATCH 161/220] Update ParticipantInfo --- .../Lounge/Components/ParticipantInfo.cs | 47 ++++--------------- .../Multi/Lounge/Components/RoomInspector.cs | 2 +- 2 files changed, 11 insertions(+), 38 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs index b0ce800d4b..1bc6d5aec0 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs @@ -2,12 +2,10 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -19,12 +17,12 @@ namespace osu.Game.Screens.Multi.Lounge.Components { public class ParticipantInfo : Container { - private readonly FillFlowContainer levelRangeContainer; + private readonly FillFlowContainer summaryContainer; public readonly IBindable Host = new Bindable(); public readonly IBindable> Participants = new Bindable>(); - public ParticipantInfo(string rankPrefix = null) + public ParticipantInfo() { RelativeSizeAxes = Axes.X; Height = 15f; @@ -49,7 +47,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Width = 22f, RelativeSizeAxes = Axes.Y, }, - new Container //todo: team banners + /*new Container //todo: team banners { Width = 38f, RelativeSizeAxes = Axes.Y, @@ -63,7 +61,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Colour = OsuColour.FromHex(@"ad387e"), }, }, - }, + },*/ hostText = new LinkFlowContainer { Anchor = Anchor.CentreLeft, @@ -72,7 +70,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components } }, }, - levelRangeContainer = new FillFlowContainer + summaryContainer = new FillFlowContainer { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -82,34 +80,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components { new OsuSpriteText { - Text = rankPrefix, + Text = "0 participants", TextSize = 14, - }, - new OsuSpriteText - { - Text = "#", - TextSize = 14, - }, - levelRangeLower = new OsuSpriteText - { - TextSize = 14, - Font = @"Exo2.0-Bold", - }, - new OsuSpriteText - { - Text = " - ", - TextSize = 14, - }, - new OsuSpriteText - { - Text = "#", - TextSize = 14, - }, - levelRangeHigher = new OsuSpriteText - { - TextSize = 14, - Font = @"Exo2.0-Bold", - }, + } }, }, }; @@ -123,18 +96,18 @@ namespace osu.Game.Screens.Multi.Lounge.Components flagContainer.Child = new DrawableFlag(v.Country) { RelativeSizeAxes = Axes.Both }; }); - Participants.BindValueChanged(v => + /*Participants.BindValueChanged(v => { var ranks = v.Select(u => u.Statistics.Ranks.Global); levelRangeLower.Text = ranks.Min().ToString(); levelRangeHigher.Text = ranks.Max().ToString(); - }); + });*/ } [BackgroundDependencyLoader] private void load(OsuColour colours) { - levelRangeContainer.Colour = colours.Gray9; + summaryContainer.Colour = colours.Gray9; } } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 08beace4ca..be16d89255 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -142,7 +142,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Padding = contentPadding, Children = new Drawable[] { - participantInfo = new ParticipantInfo(@"Rank Range "), + participantInfo = new ParticipantInfo(), }, }, }, From ae47eb61caf9ef810cd0d2d56f12164d78f45c05 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 20:42:47 +0900 Subject: [PATCH 162/220] Fix test not working when not logged in --- .../TestCaseUpdateableBeatmapBackgroundSprite.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs b/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs index 24701fccbc..bc449f645b 100644 --- a/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game.Tests/Visual/TestCaseUpdateableBeatmapBackgroundSprite.cs @@ -40,12 +40,18 @@ namespace osu.Game.Tests.Visual AddStep("imported", () => beatmapBindable.Value = imported.Beatmaps.First()); if (api.IsLoggedIn) + { AddUntilStep(() => req.Result != null, "wait for api response"); - AddStep("online", () => beatmapBindable.Value = new BeatmapInfo + AddStep("online", () => beatmapBindable.Value = new BeatmapInfo + { + BeatmapSet = req.Result?.ToBeatmapSet(rulesets) + }); + } + else { - BeatmapSet = req.Result?.ToBeatmapSet(rulesets) - }); + AddStep("online (login first)", () => { }); + } } } } From bee4e8ad28bd903a60667abc1ddd4b133a4cd110 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 21:11:31 +0900 Subject: [PATCH 163/220] Fix cancelled webrequests triggering exceptions --- osu.Game/Online/API/APIRequest.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index 41f774e83c..ae39d76384 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -92,7 +92,11 @@ namespace osu.Game.Online.API public void Fail(Exception e) { - if (cancelled) return; + if (WebRequest?.Completed == true) + return; + + if (cancelled) + return; cancelled = true; WebRequest?.Abort(); From 9901b116000ecbc16c06498198edd229a1586d72 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 17:44:36 +0900 Subject: [PATCH 164/220] Display room join errors as notifications --- osu.Game/Screens/Multi/RoomManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 0af96c2e1b..1947909438 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -73,7 +73,7 @@ namespace osu.Game.Screens.Multi RoomJoined?.Invoke(room); }; - currentJoinRoomRequest.Failure += exception => Logger.Log($"Failed to join room: {exception}"); + currentJoinRoomRequest.Failure += exception => Logger.Log($"Failed to join room: {exception}", level: LogLevel.Important); api.Queue(currentJoinRoomRequest); } From 940d4a16bbbdedfc616f0a33e45e4e3d792d2100 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 18:38:58 +0900 Subject: [PATCH 165/220] Add error message when creation fails --- .../Visual/TestCaseLoungeRoomsContainer.cs | 2 +- .../Visual/TestCaseMatchSettingsOverlay.cs | 49 +++++++++++++++++-- .../Online/API/Requests/CreateRoomRequest.cs | 3 +- .../API/Requests/Responses/APICreatedRoom.cs | 14 ++++++ osu.Game/Screens/Multi/IRoomManager.cs | 3 +- .../Match/Components/MatchSettingsOverlay.cs | 44 ++++++++++++++--- osu.Game/Screens/Multi/RoomManager.cs | 10 +++- 7 files changed, 109 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs diff --git a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs index dd7e8f7fac..e42781849d 100644 --- a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs @@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual public readonly BindableCollection Rooms = new BindableCollection(); IBindableCollection IRoomManager.Rooms => Rooms; - public void CreateRoom(Room room) => Rooms.Add(room); + public void CreateRoom(Room room, Action onError = null) => Rooms.Add(room); public void JoinRoom(Room room) => RoomJoined?.Invoke(room); diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index 3c41fd6920..a31b91cc2a 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -9,6 +9,7 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi; @@ -77,7 +78,11 @@ namespace osu.Game.Tests.Visual settings.NameField.Current.Value = expected_name; settings.DurationField.Current.Value = expectedDuration; - roomManager.CreateRequested = r => createdRoom = r; + roomManager.CreateRequested = r => + { + createdRoom = r; + return true; + }; }); AddStep("create room", () => settings.ApplyButton.Action.Invoke()); @@ -85,13 +90,40 @@ namespace osu.Game.Tests.Visual AddAssert("has correct duration", () => createdRoom.Duration.Value == expectedDuration); } - private class TestRoomSettings : MatchSettingsOverlay + [Test] + public void TestCreationFailureDisplaysError() + { + bool fail; + + AddStep("setup", () => + { + fail = true; + roomManager.CreateRequested = _ => !fail; + }); + AddAssert("error not displayed", () => !settings.ErrorText.IsPresent); + + AddStep("create room", () => settings.ApplyButton.Action.Invoke()); + AddAssert("error displayed", () => settings.ErrorText.IsPresent); + AddAssert("error has correct text", () => settings.ErrorText.Text == TestRoomManager.FAILED_TEXT); + + AddStep("create room no fail", () => + { + fail = false; + settings.ApplyButton.Action.Invoke(); + }); + + AddUntilStep(() => !settings.ErrorText.IsPresent, "error not displayed"); + } + + private class TestRoomSettings : RoomSettingsOverlay { public new TriangleButton ApplyButton => base.ApplyButton; public new OsuTextBox NameField => base.NameField; public new OsuDropdown DurationField => base.DurationField; + public new OsuSpriteText ErrorText => base.ErrorText; + public TestRoomSettings(Room room) : base(room) { @@ -100,13 +132,22 @@ namespace osu.Game.Tests.Visual private class TestRoomManager : IRoomManager { - public Action CreateRequested; + public const string FAILED_TEXT = "failed"; + + public Func CreateRequested; public event Action RoomJoined; public IBindableCollection Rooms { get; } = null; - public void CreateRoom(Room room) => CreateRequested?.Invoke(room); + public void CreateRoom(Room room, Action onError = null) + { + if (CreateRequested == null) + return; + + if (!CreateRequested.Invoke(room)) + onError?.Invoke(FAILED_TEXT); + } public void JoinRoom(Room room) => throw new NotImplementedException(); diff --git a/osu.Game/Online/API/Requests/CreateRoomRequest.cs b/osu.Game/Online/API/Requests/CreateRoomRequest.cs index 7ce289b65a..fc401be5f1 100644 --- a/osu.Game/Online/API/Requests/CreateRoomRequest.cs +++ b/osu.Game/Online/API/Requests/CreateRoomRequest.cs @@ -4,11 +4,12 @@ using System.Net.Http; using Newtonsoft.Json; using osu.Framework.IO.Network; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Multiplayer; namespace osu.Game.Online.API.Requests { - public class CreateRoomRequest : APIRequest + public class CreateRoomRequest : APIRequest { private readonly Room room; diff --git a/osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs b/osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs new file mode 100644 index 0000000000..ca0daa04b6 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; +using osu.Game.Online.Multiplayer; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APICreatedRoom : Room + { + [JsonProperty("error")] + public string Error { get; set; } + } +} diff --git a/osu.Game/Screens/Multi/IRoomManager.cs b/osu.Game/Screens/Multi/IRoomManager.cs index b94df93581..bb996f0b5c 100644 --- a/osu.Game/Screens/Multi/IRoomManager.cs +++ b/osu.Game/Screens/Multi/IRoomManager.cs @@ -24,7 +24,8 @@ namespace osu.Game.Screens.Multi /// Creates a new . /// /// The to create. - void CreateRoom(Room room); + /// An action to be invoked if an error occurred. + void CreateRoom(Room room, Action onError = null); /// /// Joins a . diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 6de2bed938..d6228b106b 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -37,6 +37,8 @@ namespace osu.Game.Screens.Multi.Match.Components protected readonly TriangleButton ApplyButton; protected readonly OsuPasswordTextBox PasswordField; + protected readonly OsuSpriteText ErrorText; + private readonly Room room; [Resolved(CanBeNull = true)] @@ -200,14 +202,31 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex(@"28242d").Darken(0.5f).Opacity(1f), }, - ApplyButton = new CreateRoomButton + new FillFlowContainer { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), Margin = new MarginPadding { Vertical = 20 }, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(230, 55), - Action = apply, - }, + Children = new Drawable[] + { + ApplyButton = new CreateRoomButton + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(230, 55), + Action = apply, + }, + ErrorText = new OsuSpriteText + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Alpha = 0, + Depth = 1 + } + } + } } } } @@ -229,6 +248,7 @@ namespace osu.Game.Screens.Multi.Match.Components private void load(OsuColour colours) { typeLabel.Colour = colours.Yellow; + ErrorText.Colour = colours.RedDark; MaxParticipantsField.ReadOnly = true; PasswordField.ReadOnly = true; @@ -258,6 +278,8 @@ namespace osu.Game.Screens.Multi.Match.Components private void apply() { + hideError(); + bindings.Name.Value = NameField.Text; bindings.Availability.Value = AvailabilityPicker.Current.Value; bindings.Type.Value = TypePicker.Current.Value; @@ -269,7 +291,15 @@ namespace osu.Game.Screens.Multi.Match.Components bindings.Duration.Value = DurationField.Current.Value; - manager?.CreateRoom(room); + manager?.CreateRoom(room, showError); + } + + private void hideError() => ErrorText.FadeOut(50); + + private void showError(string text) + { + ErrorText.Text = text; + ErrorText.FadeIn(50); } private class SettingsTextBox : OsuTextBox diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 1947909438..08458bf4e9 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -48,13 +48,19 @@ namespace osu.Game.Screens.Multi PartRoom(); } - public void CreateRoom(Room room) + public void CreateRoom(Room room, Action onError = null) { room.Host.Value = api.LocalUser; var req = new CreateRoomRequest(room); req.Success += result => addRoom(room, result); - req.Failure += exception => Logger.Log($"Failed to create room: {exception}"); + req.Failure += exception => + { + if (req.Result != null) + onError?.Invoke(req.Result.Error); + else + Logger.Log($"Failed to create the room: {exception}", level: LogLevel.Important); + }; api.Queue(req); } From 5af29f838480b35ba4c9a5c3dd8af7aadcb55871 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 20:32:01 +0900 Subject: [PATCH 166/220] Reduce code duplication --- osu.Game/Screens/Multi/RoomManager.cs | 45 ++++++++++++++++----------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 08458bf4e9..d91c05f79f 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -53,7 +53,12 @@ namespace osu.Game.Screens.Multi room.Host.Value = api.LocalUser; var req = new CreateRoomRequest(room); - req.Success += result => addRoom(room, result); + req.Success += result => + { + update(room, result); + addRoom(room); + }; + req.Failure += exception => { if (req.Result != null) @@ -120,13 +125,8 @@ namespace osu.Game.Screens.Multi // Add new matches, or update existing foreach (var r in result) { - processPlaylist(r); - - var existing = rooms.FirstOrDefault(e => e.RoomID.Value == r.RoomID.Value); - if (existing == null) - rooms.Add(r); - else - existing.CopyFrom(r); + update(r, r); + addRoom(r); } tcs.SetResult(true); @@ -139,22 +139,29 @@ namespace osu.Game.Screens.Multi return tcs.Task; } - private void addRoom(Room local, Room remote) + /// + /// Updates a local with a remote copy. + /// + /// The local to update. + /// The remote to update with. + private void update(Room local, Room remote) { - processPlaylist(remote); - + foreach (var pi in remote.Playlist) + pi.MapObjects(beatmaps, rulesets); local.CopyFrom(remote); - - var existing = rooms.FirstOrDefault(e => e.RoomID.Value == local.RoomID.Value); - if (existing != null) - rooms.Remove(existing); - rooms.Add(local); } - private void processPlaylist(Room room) + /// + /// Adds a to the list of available rooms. + /// + /// The to add.< + private void addRoom(Room room) { - foreach (var pi in room.Playlist) - pi.MapObjects(beatmaps, rulesets); + var existing = rooms.FirstOrDefault(e => e.RoomID.Value == room.RoomID.Value); + if (existing == null) + rooms.Add(room); + else + existing.CopyFrom(room); } } } From 2e5cd8b4e3c845b46a9fdb321b1458da36137f09 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 20:33:49 +0900 Subject: [PATCH 167/220] Fix post-rebase errors --- osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index a31b91cc2a..f93d1b3069 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual AddUntilStep(() => !settings.ErrorText.IsPresent, "error not displayed"); } - private class TestRoomSettings : RoomSettingsOverlay + private class TestRoomSettings : MatchSettingsOverlay { public new TriangleButton ApplyButton => base.ApplyButton; From 26834abd33c33caf076bdfbc3be51c75a210997c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 21:18:55 +0900 Subject: [PATCH 168/220] Fade and no schedule --- .../Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs | 2 +- osu.Game/Screens/Multi/Match/Components/Header.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index fd00576d21..93783f757b 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -20,7 +20,7 @@ namespace osu.Game.Beatmaps.Drawables public UpdateableBeatmapBackgroundSprite() { - Beatmap.BindValueChanged(b => Schedule(() => Model = b)); + Beatmap.BindValueChanged(b => Model = b); } protected override Drawable CreateDrawable(BeatmapInfo model) diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 4feca7dccb..4f4d5a1d4e 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -140,7 +140,7 @@ namespace osu.Game.Screens.Multi.Match.Components private class HeaderBeatmapBackgroundSprite : UpdateableBeatmapBackgroundSprite { - protected override double FadeDuration => 0; + protected override double FadeDuration => 200; } } } From 0c384417f152d52b62f4aff2119a008fa2203f8b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 20:45:56 +0900 Subject: [PATCH 169/220] Add processing overlay to room creation process --- .../Visual/TestCaseLoungeRoomsContainer.cs | 2 +- .../Visual/TestCaseMatchSettingsOverlay.cs | 4 +++- osu.Game/Screens/Multi/IRoomManager.cs | 3 ++- .../Match/Components/MatchSettingsOverlay.cs | 17 +++++++++++++---- osu.Game/Screens/Multi/RoomManager.cs | 4 +++- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs index e42781849d..5ecd09e885 100644 --- a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs @@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual public readonly BindableCollection Rooms = new BindableCollection(); IBindableCollection IRoomManager.Rooms => Rooms; - public void CreateRoom(Room room, Action onError = null) => Rooms.Add(room); + public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) => Rooms.Add(room); public void JoinRoom(Room room) => RoomJoined?.Invoke(room); diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index f93d1b3069..086e6fbefe 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -140,13 +140,15 @@ namespace osu.Game.Tests.Visual public IBindableCollection Rooms { get; } = null; - public void CreateRoom(Room room, Action onError = null) + public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) { if (CreateRequested == null) return; if (!CreateRequested.Invoke(room)) onError?.Invoke(FAILED_TEXT); + else + onSuccess?.Invoke(); } public void JoinRoom(Room room) => throw new NotImplementedException(); diff --git a/osu.Game/Screens/Multi/IRoomManager.cs b/osu.Game/Screens/Multi/IRoomManager.cs index bb996f0b5c..0e051802e3 100644 --- a/osu.Game/Screens/Multi/IRoomManager.cs +++ b/osu.Game/Screens/Multi/IRoomManager.cs @@ -24,8 +24,9 @@ namespace osu.Game.Screens.Multi /// Creates a new . /// /// The to create. + /// An action to be invoked if the creation succeeds. /// An action to be invoked if an error occurred. - void CreateRoom(Room room, Action onError = null); + void CreateRoom(Room room, Action onSuccess = null, Action onError = null); /// /// Joins a . diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index d6228b106b..916a21fb71 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -39,6 +39,8 @@ namespace osu.Game.Screens.Multi.Match.Components protected readonly OsuSpriteText ErrorText; + private readonly ProcessingOverlay processingOverlay; + private readonly Room room; [Resolved(CanBeNull = true)] @@ -231,7 +233,8 @@ namespace osu.Game.Screens.Multi.Match.Components } } } - } + }, + processingOverlay = new ProcessingOverlay { Alpha = 0 } }, }; @@ -264,7 +267,7 @@ namespace osu.Game.Screens.Multi.Match.Components ApplyButton.Enabled.Value = hasValidSettings; } - private bool hasValidSettings => NameField.Text.Length > 0 && bindings.Playlist.Count > 0; + private bool hasValidSettings => bindings.Room.RoomID.Value == null && NameField.Text.Length > 0 && bindings.Playlist.Count > 0; protected override void PopIn() { @@ -291,15 +294,21 @@ namespace osu.Game.Screens.Multi.Match.Components bindings.Duration.Value = DurationField.Current.Value; - manager?.CreateRoom(room, showError); + manager?.CreateRoom(room, onSuccess, onError); + + processingOverlay.Show(); } private void hideError() => ErrorText.FadeOut(50); - private void showError(string text) + private void onSuccess() => processingOverlay.Hide(); + + private void onError(string text) { ErrorText.Text = text; ErrorText.FadeIn(50); + + processingOverlay.Hide(); } private class SettingsTextBox : OsuTextBox diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index d91c05f79f..642084547c 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Multi PartRoom(); } - public void CreateRoom(Room room, Action onError = null) + public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) { room.Host.Value = api.LocalUser; @@ -57,6 +57,8 @@ namespace osu.Game.Screens.Multi { update(room, result); addRoom(room); + + onSuccess?.Invoke(); }; req.Failure += exception => From 152f3b1da3ee2e82216e16c35be3677e5ec7c039 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 21:10:31 +0900 Subject: [PATCH 170/220] Add processing overlay to lounge screen --- .../Visual/TestCaseLoungeRoomsContainer.cs | 8 +-- .../Visual/TestCaseMatchSettingsOverlay.cs | 8 ++- osu.Game/Screens/Multi/IRoomManager.cs | 11 ++-- .../Screens/Multi/Lounge/LoungeSubScreen.cs | 51 ++++++++++--------- .../Match/Components/MatchSettingsOverlay.cs | 2 +- osu.Game/Screens/Multi/RoomManager.cs | 16 +++--- 6 files changed, 49 insertions(+), 47 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs index 5ecd09e885..e9dfb0f041 100644 --- a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs @@ -71,14 +71,14 @@ namespace osu.Game.Tests.Visual private class TestRoomManager : IRoomManager { - public event Action RoomJoined; - public readonly BindableCollection Rooms = new BindableCollection(); IBindableCollection IRoomManager.Rooms => Rooms; - public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) => Rooms.Add(room); + public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) => Rooms.Add(room); - public void JoinRoom(Room room) => RoomJoined?.Invoke(room); + public void JoinRoom(Room room, Action onSuccess = null, Action onError = null) + { + } public void PartRoom() { diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index 086e6fbefe..afce8999b4 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -136,11 +136,9 @@ namespace osu.Game.Tests.Visual public Func CreateRequested; - public event Action RoomJoined; - public IBindableCollection Rooms { get; } = null; - public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) + public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) { if (CreateRequested == null) return; @@ -148,10 +146,10 @@ namespace osu.Game.Tests.Visual if (!CreateRequested.Invoke(room)) onError?.Invoke(FAILED_TEXT); else - onSuccess?.Invoke(); + onSuccess?.Invoke(room); } - public void JoinRoom(Room room) => throw new NotImplementedException(); + public void JoinRoom(Room room, Action onSuccess = null, Action onError = null) => throw new NotImplementedException(); public void PartRoom() => throw new NotImplementedException(); diff --git a/osu.Game/Screens/Multi/IRoomManager.cs b/osu.Game/Screens/Multi/IRoomManager.cs index 0e051802e3..a929e1a0f7 100644 --- a/osu.Game/Screens/Multi/IRoomManager.cs +++ b/osu.Game/Screens/Multi/IRoomManager.cs @@ -10,11 +10,6 @@ namespace osu.Game.Screens.Multi { public interface IRoomManager { - /// - /// Invoked when a room is joined. - /// - event Action RoomJoined; - /// /// All the active s. /// @@ -26,13 +21,15 @@ namespace osu.Game.Screens.Multi /// The to create. /// An action to be invoked if the creation succeeds. /// An action to be invoked if an error occurred. - void CreateRoom(Room room, Action onSuccess = null, Action onError = null); + void CreateRoom(Room room, Action onSuccess = null, Action onError = null); /// /// Joins a . /// /// The to join. must be populated. - void JoinRoom(Room room); + /// + /// + void JoinRoom(Room room, Action onSuccess = null, Action onError = null); /// /// Parts the currently-joined . diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index aef8265130..83f91536d3 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osu.Framework.Screens; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.SearchableList; using osu.Game.Screens.Multi.Lounge.Components; @@ -21,6 +22,7 @@ namespace osu.Game.Screens.Multi.Lounge private readonly Container content; private readonly RoomsContainer rooms; private readonly Action pushGameplayScreen; + private readonly ProcessingOverlay processingOverlay; [Resolved(CanBeNull = true)] private IRoomManager roomManager { get; set; } @@ -43,18 +45,26 @@ namespace osu.Game.Screens.Multi.Lounge RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - new ScrollContainer + new Container { RelativeSizeAxes = Axes.Both, Width = 0.55f, - ScrollbarOverlapsContent = false, - Padding = new MarginPadding(10), - Child = new SearchContainer + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = rooms = new RoomsContainer { JoinRequested = r => roomManager?.JoinRoom(r) } - }, + new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + ScrollbarOverlapsContent = false, + Padding = new MarginPadding(10), + Child = new SearchContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = rooms = new RoomsContainer { JoinRequested = joinRequested } + }, + }, + processingOverlay = new ProcessingOverlay { Alpha = 0 } + } }, inspector = new RoomInspector { @@ -74,13 +84,6 @@ namespace osu.Game.Screens.Multi.Lounge Filter.Search.Exit += Exit; } - [BackgroundDependencyLoader] - private void load() - { - if (roomManager != null) - roomManager.RoomJoined += Push; - } - protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -123,6 +126,16 @@ namespace osu.Game.Screens.Multi.Lounge roomManager?.Filter(Filter.CreateCriteria()); } + private void joinRequested(Room room) + { + processingOverlay.Show(); + roomManager?.JoinRoom(room, r => + { + Open(room); + processingOverlay.Hide(); + }, _ => processingOverlay.Hide()); + } + /// /// Push a room as a new subscreen. /// @@ -134,13 +147,5 @@ namespace osu.Game.Screens.Multi.Lounge Push(new MatchSubScreen(room, s => pushGameplayScreen?.Invoke(s))); } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (roomManager != null) - roomManager.RoomJoined -= Push; - } } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 916a21fb71..1210b9379f 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -301,7 +301,7 @@ namespace osu.Game.Screens.Multi.Match.Components private void hideError() => ErrorText.FadeOut(50); - private void onSuccess() => processingOverlay.Hide(); + private void onSuccess(Room room) => processingOverlay.Hide(); private void onError(string text) { diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 642084547c..6ddfd0fab1 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -19,8 +19,6 @@ namespace osu.Game.Screens.Multi { public class RoomManager : PollingComponent, IRoomManager { - public event Action RoomJoined; - private readonly BindableCollection rooms = new BindableCollection(); public IBindableCollection Rooms => rooms; @@ -48,7 +46,7 @@ namespace osu.Game.Screens.Multi PartRoom(); } - public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) + public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) { room.Host.Value = api.LocalUser; @@ -58,7 +56,7 @@ namespace osu.Game.Screens.Multi update(room, result); addRoom(room); - onSuccess?.Invoke(); + onSuccess?.Invoke(room); }; req.Failure += exception => @@ -74,7 +72,7 @@ namespace osu.Game.Screens.Multi private JoinRoomRequest currentJoinRoomRequest; - public void JoinRoom(Room room) + public void JoinRoom(Room room, Action onSuccess = null, Action onError = null) { currentJoinRoomRequest?.Cancel(); currentJoinRoomRequest = null; @@ -83,10 +81,14 @@ namespace osu.Game.Screens.Multi currentJoinRoomRequest.Success += () => { currentRoom = room; - RoomJoined?.Invoke(room); + onSuccess?.Invoke(room); }; - currentJoinRoomRequest.Failure += exception => Logger.Log($"Failed to join room: {exception}", level: LogLevel.Important); + currentJoinRoomRequest.Failure += exception => + { + Logger.Log($"Failed to join room: {exception}", level: LogLevel.Important); + onError?.Invoke(exception.ToString()); + }; api.Queue(currentJoinRoomRequest); } From 2d19436456a1fa177fd07339c839a3fac5451b9d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 21:21:26 +0900 Subject: [PATCH 171/220] Open -> Push --- osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index 83f91536d3..d9633218eb 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -131,7 +131,7 @@ namespace osu.Game.Screens.Multi.Lounge processingOverlay.Show(); roomManager?.JoinRoom(room, r => { - Open(room); + Push(room); processingOverlay.Hide(); }, _ => processingOverlay.Hide()); } From a1fa914c66fdb41209bcfeb019381296ee5fb07d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 21:58:14 +0900 Subject: [PATCH 172/220] Participants --- osu.Game/Online/Multiplayer/Room.cs | 4 ++++ osu.Game/Screens/Multi/Components/ParticipantCount.cs | 6 ++++-- osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs | 1 + .../Screens/Multi/Lounge/Components/ParticipantInfo.cs | 7 ++++++- osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs | 7 +++++-- osu.Game/Screens/Multi/Match/Components/Participants.cs | 6 ++++-- osu.Game/Screens/Multi/RoomBindings.cs | 3 +++ 7 files changed, 27 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index b17d08320c..d7898297c9 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -49,6 +49,9 @@ namespace osu.Game.Online.Multiplayer [JsonIgnore] public Bindable> Participants { get; private set; } = new Bindable>(Enumerable.Empty()); + [JsonProperty("participant_count")] + public Bindable ParticipantCount { get; private set; } = new Bindable(); + [JsonProperty("duration")] private int duration { @@ -85,6 +88,7 @@ namespace osu.Game.Online.Multiplayer Type.Value = other.Type; MaxParticipants.Value = other.MaxParticipants; + ParticipantCount.Value = other.ParticipantCount.Value; Participants.Value = other.Participants.Value.ToArray(); EndDate.Value = other.EndDate; diff --git a/osu.Game/Screens/Multi/Components/ParticipantCount.cs b/osu.Game/Screens/Multi/Components/ParticipantCount.cs index 8665678562..fc19039872 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantCount.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantCount.cs @@ -11,7 +11,7 @@ using osu.Game.Users; namespace osu.Game.Screens.Multi.Components { - public class ParticipantCount : CompositeDrawable + public class ParticipantCountDisplay : CompositeDrawable { private const float text_size = 30; private const float transition_duration = 100; @@ -19,9 +19,10 @@ namespace osu.Game.Screens.Multi.Components private readonly OsuSpriteText slash, maxText; public readonly IBindable> Participants = new Bindable>(); + public readonly IBindable ParticipantCount = new Bindable(); public readonly IBindable MaxParticipants = new Bindable(); - public ParticipantCount() + public ParticipantCountDisplay() { AutoSizeAxes = Axes.Both; @@ -55,6 +56,7 @@ namespace osu.Game.Screens.Multi.Components Participants.BindValueChanged(v => count.Text = v.Count().ToString()); MaxParticipants.BindValueChanged(_ => updateMax(), true); + ParticipantCount.BindValueChanged(v => count.Text = v.ToString("#,0")); } private void updateMax() diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index d62b628389..0540eed1aa 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -217,6 +217,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components modeTypeInfo.Type.BindTo(bindings.Type); participantInfo.Host.BindTo(bindings.Host); participantInfo.Participants.BindTo(bindings.Participants); + participantInfo.ParticipantCount.BindTo(bindings.ParticipantCount); bindings.Name.BindValueChanged(n => name.Text = n, true); bindings.EndDate.BindValueChanged(d => endDate.Date = d, true); diff --git a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs index 1bc6d5aec0..34fc7fe886 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using Humanizer; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -21,9 +22,11 @@ namespace osu.Game.Screens.Multi.Lounge.Components public readonly IBindable Host = new Bindable(); public readonly IBindable> Participants = new Bindable>(); + public readonly IBindable ParticipantCount = new Bindable(); public ParticipantInfo() { + OsuSpriteText summary; RelativeSizeAxes = Axes.X; Height = 15f; @@ -78,7 +81,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Direction = FillDirection.Horizontal, Children = new[] { - new OsuSpriteText + summary = new OsuSpriteText { Text = "0 participants", TextSize = 14, @@ -96,6 +99,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components flagContainer.Child = new DrawableFlag(v.Country) { RelativeSizeAxes = Axes.Both }; }); + ParticipantCount.BindValueChanged(v => summary.Text = $"{v:#,0}{" participant".Pluralize(v == 1)}"); + /*Participants.BindValueChanged(v => { var ranks = v.Select(u => u.Statistics.Ranks.Global); diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index be16d89255..a7fa592323 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components private OsuColour colours; private Box statusStrip; private UpdateableBeatmapBackgroundSprite background; - private ParticipantCount participantCount; + private ParticipantCountDisplay participantCount; private FillFlowContainer topFlow, participantsFlow; private OsuSpriteText name, status; private BeatmapTypeInfo beatmapTypeInfo; @@ -84,7 +84,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Padding = new MarginPadding(20), Children = new Drawable[] { - participantCount = new ParticipantCount + participantCount = new ParticipantCountDisplay { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -167,9 +167,12 @@ namespace osu.Game.Screens.Multi.Lounge.Components }; participantInfo.Host.BindTo(bindings.Host); + participantInfo.ParticipantCount.BindTo(bindings.ParticipantCount); participantInfo.Participants.BindTo(bindings.Participants); + participantCount.Participants.BindTo(bindings.Participants); participantCount.MaxParticipants.BindTo(bindings.MaxParticipants); + beatmapTypeInfo.Type.BindTo(bindings.Type); background.Beatmap.BindTo(bindings.CurrentBeatmap); beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); diff --git a/osu.Game/Screens/Multi/Match/Components/Participants.cs b/osu.Game/Screens/Multi/Match/Components/Participants.cs index 4f18fc9f4c..56c8c3e8fc 100644 --- a/osu.Game/Screens/Multi/Match/Components/Participants.cs +++ b/osu.Game/Screens/Multi/Match/Components/Participants.cs @@ -16,12 +16,13 @@ namespace osu.Game.Screens.Multi.Match.Components public class Participants : CompositeDrawable { public readonly IBindable> Users = new Bindable>(); + public readonly IBindable ParticipantCount = new Bindable(); public readonly IBindable MaxParticipants = new Bindable(); public Participants() { FillFlowContainer usersFlow; - ParticipantCount count; + ParticipantCountDisplay count; InternalChild = new Container { @@ -35,7 +36,7 @@ namespace osu.Game.Screens.Multi.Match.Components Padding = new MarginPadding { Top = 10 }, Children = new Drawable[] { - count = new ParticipantCount + count = new ParticipantCountDisplay { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -55,6 +56,7 @@ namespace osu.Game.Screens.Multi.Match.Components }; count.Participants.BindTo(Users); + count.ParticipantCount.BindTo(ParticipantCount); count.MaxParticipants.BindTo(MaxParticipants); Users.BindValueChanged(v => diff --git a/osu.Game/Screens/Multi/RoomBindings.cs b/osu.Game/Screens/Multi/RoomBindings.cs index e84fa9c261..9a38ba1f60 100644 --- a/osu.Game/Screens/Multi/RoomBindings.cs +++ b/osu.Game/Screens/Multi/RoomBindings.cs @@ -45,6 +45,7 @@ namespace osu.Game.Screens.Multi Type.UnbindFrom(room.Type); Playlist.UnbindFrom(room.Playlist); Participants.UnbindFrom(room.Participants); + ParticipantCount.UnbindFrom(room.ParticipantCount); MaxParticipants.UnbindFrom(room.MaxParticipants); EndDate.UnbindFrom(room.EndDate); Availability.UnbindFrom(room.Availability); @@ -61,6 +62,7 @@ namespace osu.Game.Screens.Multi Type.BindTo(room.Type); Playlist.BindTo(room.Playlist); Participants.BindTo(room.Participants); + ParticipantCount.BindTo(room.ParticipantCount); MaxParticipants.BindTo(room.MaxParticipants); EndDate.BindTo(room.EndDate); Availability.BindTo(room.Availability); @@ -86,6 +88,7 @@ namespace osu.Game.Screens.Multi public readonly Bindable Type = new Bindable(); public readonly BindableCollection Playlist = new BindableCollection(); public readonly Bindable> Participants = new Bindable>(); + public readonly Bindable ParticipantCount = new Bindable(); public readonly Bindable MaxParticipants = new Bindable(); public readonly Bindable EndDate = new Bindable(); public readonly Bindable Availability = new Bindable(); From e7310a16c7b9d3fec811f6a7c7c484445fdabdfc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Dec 2018 22:14:49 +0900 Subject: [PATCH 173/220] Fix playlist not updating correcly --- osu.Game/Online/Multiplayer/PlaylistItem.cs | 2 +- osu.Game/Online/Multiplayer/Room.cs | 2 ++ osu.Game/Screens/Multi/RoomManager.cs | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Multiplayer/PlaylistItem.cs b/osu.Game/Online/Multiplayer/PlaylistItem.cs index e887295f4a..4155121bdf 100644 --- a/osu.Game/Online/Multiplayer/PlaylistItem.cs +++ b/osu.Game/Online/Multiplayer/PlaylistItem.cs @@ -66,7 +66,7 @@ namespace osu.Game.Online.Multiplayer public void MapObjects(BeatmapManager beatmaps, RulesetStore rulesets) { // If we don't have an api beatmap, the request occurred as a result of room creation, so we can query the local beatmap instead - // Todo: Is this a bug? + // Todo: Is this a bug? Room creation only returns the beatmap ID Beatmap = apiBeatmap == null ? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == BeatmapID) : apiBeatmap.ToBeatmap(rulesets); Ruleset = rulesets.GetRuleset(RulesetID); diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index d7898297c9..924bf75809 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -95,6 +95,8 @@ namespace osu.Game.Online.Multiplayer // Todo: Temporary, should only remove/add new items (requires framework changes) if (Playlist.Count == 0) Playlist.AddRange(other.Playlist); + else if (other.Playlist.Count > 0) + Playlist.First().ID = other.Playlist.First().ID; } public bool ShouldSerializeRoomID() => false; diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index c24ef4664f..552f24df8a 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -154,7 +154,9 @@ namespace osu.Game.Screens.Multi { foreach (var pi in remote.Playlist) pi.MapObjects(beatmaps, rulesets); - local.CopyFrom(remote); + + if (local != remote) + local.CopyFrom(remote); } /// From 8cf30bdb6a8cbb84e48be1e4d931e38499d8ea4d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 22:16:35 +0900 Subject: [PATCH 174/220] Play with delegate --- osu.Game.Tests/Visual/TestCasePlayerLoader.cs | 6 ++-- osu.Game/OsuGame.cs | 2 +- .../Screens/Multi/Match/MatchSubScreen.cs | 8 +++-- osu.Game/Screens/Play/PlayerLoader.cs | 35 ++++++++++++------- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/TestCasePlayerLoader.cs index de839a21af..6ec3bd108b 100644 --- a/osu.Game.Tests/Visual/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/TestCasePlayerLoader.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual { Beatmap.Value = new DummyWorkingBeatmap(game); - AddStep("load dummy beatmap", () => Add(loader = new PlayerLoader(new Player + AddStep("load dummy beatmap", () => Add(loader = new PlayerLoader(() => new Player { AllowPause = false, AllowLeadIn = false, @@ -30,9 +30,9 @@ namespace osu.Game.Tests.Visual AddStep("load slow dummy beatmap", () => { - SlowLoadPlayer slow; + SlowLoadPlayer slow = null; - Add(loader = new PlayerLoader(slow = new SlowLoadPlayer + Add(loader = new PlayerLoader(() => slow = new SlowLoadPlayer { AllowPause = false, AllowLeadIn = false, diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 41f2caf40e..6a5f9656d1 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -317,7 +317,7 @@ namespace osu.Game Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); Beatmap.Value.Mods.Value = databasedScoreInfo.Mods; - currentScreen.Push(new PlayerLoader(new ReplayPlayer(databasedScore))); + currentScreen.Push(new PlayerLoader(() => new ReplayPlayer(databasedScore))); } } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 982f54f7c8..5cd5d9e76a 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -167,10 +167,12 @@ namespace osu.Game.Screens.Multi.Match { default: case GameTypeTimeshift _: - var player = new TimeshiftPlayer(room, room.Playlist.First().ID); - player.Exited += _ => leaderboard.RefreshScores(); + pushGameplayScreen?.Invoke(new PlayerLoader(() => { + var player = new TimeshiftPlayer(room, room.Playlist.First().ID); + player.Exited += _ => leaderboard.RefreshScores(); - pushGameplayScreen?.Invoke(new PlayerLoader(player)); + return player; + })); break; } } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index bf44a60473..ded25f013a 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -24,6 +25,7 @@ namespace osu.Game.Screens.Play { public class PlayerLoader : ScreenWithBeatmapBackground { + private readonly Func createPlayer; private static readonly Vector2 background_blur = new Vector2(15); private Player player; @@ -35,15 +37,15 @@ namespace osu.Game.Screens.Play private Task loadTask; - public PlayerLoader(Player player) + public PlayerLoader(Func createPlayer) { - this.player = player; + this.createPlayer = createPlayer; + } - player.RestartRequested = () => - { - hideOverlays = true; - ValidForResume = true; - }; + private void restartRequested() + { + hideOverlays = true; + ValidForResume = true; } [BackgroundDependencyLoader] @@ -71,7 +73,7 @@ namespace osu.Game.Screens.Play } }); - loadTask = LoadComponentAsync(player, playerLoaded); + loadNewPlayer(); } private void playerLoaded(Player player) => info.Loading = false; @@ -85,15 +87,22 @@ namespace osu.Game.Screens.Play info.Loading = true; //we will only be resumed if the player has requested a re-run (see ValidForResume setting above) - loadTask = LoadComponentAsync(player = new Player - { - RestartCount = player.RestartCount + 1, - RestartRequested = player.RestartRequested, - }, playerLoaded); + loadNewPlayer(); this.Delay(400).Schedule(pushWhenLoaded); } + private void loadNewPlayer() + { + var restartCount = player?.RestartCount + 1 ?? 0; + + player = createPlayer(); + player.RestartCount = restartCount; + player.RestartRequested = restartRequested; + + loadTask = LoadComponentAsync(player, playerLoaded); + } + private void contentIn() { Content.ScaleTo(1, 650, Easing.OutQuint); diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index cbe22d968a..a7de93b11d 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -62,7 +62,7 @@ namespace osu.Game.Screens.Select SampleConfirm?.Play(); - LoadComponentAsync(player = new PlayerLoader(new Player()), l => + LoadComponentAsync(player = new PlayerLoader(() => new Player()), l => { if (IsCurrentScreen) Push(player); }); From 6b7b0af2e4d22a9ba45554fe02a611f318179bc4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 22:25:15 +0900 Subject: [PATCH 175/220] Temporary fix for participant count being nullable --- osu.Game/Online/Multiplayer/Room.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 924bf75809..c517b5aef5 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -49,9 +49,17 @@ namespace osu.Game.Online.Multiplayer [JsonIgnore] public Bindable> Participants { get; private set; } = new Bindable>(Enumerable.Empty()); - [JsonProperty("participant_count")] + public Bindable ParticipantCount { get; private set; } = new Bindable(); + // todo: TEMPORARY + [JsonProperty("participant_count")] + private int? participantCount + { + get => ParticipantCount; + set => ParticipantCount.Value = value ?? 0; + } + [JsonProperty("duration")] private int duration { From cc1f3d54b017be1193919eb1953c6f11d1ce66f4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 22:37:09 +0900 Subject: [PATCH 176/220] Fix looping failure --- osu.Game/Screens/Multi/Multiplayer.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 40f66811f7..499198d800 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -134,9 +134,18 @@ namespace osu.Game.Screens.Multi Content.ScaleTo(1.1f, 250, Easing.InSine); Content.FadeOut(250); + cancelLooping(); + base.OnSuspending(next); } + private void cancelLooping() + { + var track = Beatmap.Value.Track; + if (track != null) + track.Looping = false; + } + protected override void LogoExiting(OsuLogo logo) { // the wave overlay transition takes longer than expected to run. @@ -148,6 +157,8 @@ namespace osu.Game.Screens.Multi { base.Update(); + if (!IsCurrentScreen) return; + if (currentScreen is MatchSubScreen) { var track = Beatmap.Value.Track; @@ -180,11 +191,7 @@ namespace osu.Game.Screens.Multi private void screenRemoved(Screen newScreen) { if (currentScreen is MatchSubScreen) - { - var track = Beatmap.Value.Track; - if (track != null) - track.Looping = false; - } + cancelLooping(); currentScreen = (OsuScreen)newScreen; } From bb502769c72ba0d86832eaaaf7bad7211d782799 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Dec 2018 22:42:17 +0900 Subject: [PATCH 177/220] Fix enum --- osu.Game/Scoring/ScoreInfo.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index 8ffade1e2b..b863566967 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Rulesets; @@ -20,6 +21,7 @@ namespace osu.Game.Scoring public int ID { get; set; } [JsonProperty("rank")] + [JsonConverter(typeof(StringEnumConverter))] public ScoreRank Rank { get; set; } [JsonProperty("total_score")] From 1e71c5c9c4959296bd0d936bf2d3b6c840612a18 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 13:30:36 +0900 Subject: [PATCH 178/220] Add + set ended room status --- osu.Game.Tests/Visual/TestCaseMatchInfo.cs | 1 + osu.Game.Tests/Visual/TestCaseRoomStatus.cs | 50 +++++++++++++++++++ osu.Game/Online/Multiplayer/Room.cs | 4 ++ osu.Game/Online/Multiplayer/RoomStatus.cs | 12 ----- .../RoomStatuses/RoomStatusEnded.cs | 14 ++++++ .../RoomStatuses/RoomStatusOpen.cs | 14 ++++++ .../RoomStatuses/RoomStatusPlaying.cs | 14 ++++++ osu.Game/Screens/Multi/RoomManager.cs | 3 +- 8 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseRoomStatus.cs create mode 100644 osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusEnded.cs create mode 100644 osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusOpen.cs create mode 100644 osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusPlaying.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs index be3367bf6c..4da500427b 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; +using osu.Game.Online.Multiplayer.RoomStatuses; using osu.Game.Rulesets; using osu.Game.Screens.Multi.Match.Components; diff --git a/osu.Game.Tests/Visual/TestCaseRoomStatus.cs b/osu.Game.Tests/Visual/TestCaseRoomStatus.cs new file mode 100644 index 0000000000..d44b399a95 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseRoomStatus.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.Multiplayer; +using osu.Game.Online.Multiplayer.RoomStatuses; +using osu.Game.Screens.Multi.Lounge.Components; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseRoomStatus : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(RoomStatusEnded), + typeof(RoomStatusOpen), + typeof(RoomStatusPlaying) + }; + + public TestCaseRoomStatus() + { + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Width = 0.5f, + Children = new Drawable[] + { + new DrawableRoom(new Room + { + Name = { Value = "Room 1" }, + Status = { Value = new RoomStatusOpen() } + }), + new DrawableRoom(new Room + { + Name = { Value = "Room 2" }, + Status = { Value = new RoomStatusPlaying() } + }), + new DrawableRoom(new Room + { + Name = { Value = "Room 3" }, + Status = { Value = new RoomStatusEnded() } + }), + } + }; + } + } +} diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index c517b5aef5..80558b14db 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -7,6 +7,7 @@ using System.Linq; using Newtonsoft.Json; using osu.Framework.Configuration; using osu.Game.Online.Multiplayer.GameTypes; +using osu.Game.Online.Multiplayer.RoomStatuses; using osu.Game.Users; namespace osu.Game.Online.Multiplayer @@ -100,6 +101,9 @@ namespace osu.Game.Online.Multiplayer Participants.Value = other.Participants.Value.ToArray(); EndDate.Value = other.EndDate; + if (DateTimeOffset.Now >= EndDate.Value) + Status.Value = new RoomStatusEnded(); + // Todo: Temporary, should only remove/add new items (requires framework changes) if (Playlist.Count == 0) Playlist.AddRange(other.Playlist); diff --git a/osu.Game/Online/Multiplayer/RoomStatus.cs b/osu.Game/Online/Multiplayer/RoomStatus.cs index 7c6e71a360..e2d84500a9 100644 --- a/osu.Game/Online/Multiplayer/RoomStatus.cs +++ b/osu.Game/Online/Multiplayer/RoomStatus.cs @@ -11,16 +11,4 @@ namespace osu.Game.Online.Multiplayer public abstract string Message { get; } public abstract Color4 GetAppropriateColour(OsuColour colours); } - - public class RoomStatusOpen : RoomStatus - { - public override string Message => @"Welcoming Players"; - public override Color4 GetAppropriateColour(OsuColour colours) => colours.GreenLight; - } - - public class RoomStatusPlaying : RoomStatus - { - public override string Message => @"Now Playing"; - public override Color4 GetAppropriateColour(OsuColour colours) => colours.Purple; - } } diff --git a/osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusEnded.cs b/osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusEnded.cs new file mode 100644 index 0000000000..e6ab3ab495 --- /dev/null +++ b/osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusEnded.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Graphics; +using osuTK.Graphics; + +namespace osu.Game.Online.Multiplayer.RoomStatuses +{ + public class RoomStatusEnded : RoomStatus + { + public override string Message => @"Ended"; + public override Color4 GetAppropriateColour(OsuColour colours) => colours.YellowDarker; + } +} diff --git a/osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusOpen.cs b/osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusOpen.cs new file mode 100644 index 0000000000..6bc701feda --- /dev/null +++ b/osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusOpen.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Graphics; +using osuTK.Graphics; + +namespace osu.Game.Online.Multiplayer.RoomStatuses +{ + public class RoomStatusOpen : RoomStatus + { + public override string Message => @"Welcoming Players"; + public override Color4 GetAppropriateColour(OsuColour colours) => colours.GreenLight; + } +} diff --git a/osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusPlaying.cs b/osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusPlaying.cs new file mode 100644 index 0000000000..a725aca03a --- /dev/null +++ b/osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusPlaying.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Graphics; +using osuTK.Graphics; + +namespace osu.Game.Online.Multiplayer.RoomStatuses +{ + public class RoomStatusPlaying : RoomStatus + { + public override string Message => @"Now Playing"; + public override Color4 GetAppropriateColour(OsuColour colours) => colours.Purple; + } +} diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 552f24df8a..ceecaf5443 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -155,8 +155,7 @@ namespace osu.Game.Screens.Multi foreach (var pi in remote.Playlist) pi.MapObjects(beatmaps, rulesets); - if (local != remote) - local.CopyFrom(remote); + local.CopyFrom(remote); } /// From 67e200e1b2e5bd98cc744c62897352938e1b8e4c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 15:30:02 +0900 Subject: [PATCH 179/220] Leaderboard design updates --- ...ultiResults.cs => TestCaseMatchResults.cs} | 18 +++-- osu.Game.Tests/Visual/TestCaseResults.cs | 2 +- osu.Game/Online/Leaderboards/Leaderboard.cs | 66 +++++++++++-------- .../Online/Leaderboards/LeaderboardScore.cs | 4 +- .../Screens/Multi/Ranking/MatchResults.cs | 2 +- ...gResultsPage.cs => RoomLeaderboardPage.cs} | 59 ++++++++++++++--- .../Ranking/Types/RoomLeaderboardPageInfo.cs | 4 +- osu.Game/Screens/Play/SoloResults.cs | 2 +- ...ResultsPage.cs => LocalLeaderboardPage.cs} | 6 +- ...ageInfo.cs => LocalLeaderboardPageInfo.cs} | 10 +-- .../Select/Leaderboards/BeatmapLeaderboard.cs | 2 + 11 files changed, 118 insertions(+), 57 deletions(-) rename osu.Game.Tests/Visual/{TestCaseMultiResults.cs => TestCaseMatchResults.cs} (85%) rename osu.Game/Screens/Multi/Ranking/Pages/{RoomRankingResultsPage.cs => RoomLeaderboardPage.cs} (61%) rename osu.Game/Screens/Ranking/Pages/{RankingResultsPage.cs => LocalLeaderboardPage.cs} (85%) rename osu.Game/Screens/Ranking/Types/{BeatmapLeaderboardPageInfo.cs => LocalLeaderboardPageInfo.cs} (59%) diff --git a/osu.Game.Tests/Visual/TestCaseMultiResults.cs b/osu.Game.Tests/Visual/TestCaseMatchResults.cs similarity index 85% rename from osu.Game.Tests/Visual/TestCaseMultiResults.cs rename to osu.Game.Tests/Visual/TestCaseMatchResults.cs index 8991782835..086f329608 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiResults.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchResults.cs @@ -19,13 +19,13 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual { - public class TestCaseMultiResults : OsuTestCase + public class TestCaseMatchResults : OsuTestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(MatchResults), typeof(RoomLeaderboardPageInfo), - typeof(RoomRankingResultsPage) + typeof(RoomLeaderboardPage) }; [Resolved] @@ -49,7 +49,11 @@ namespace osu.Game.Tests.Visual private readonly Room room; public TestMatchResults(ScoreInfo score) - : this(score, new Room()) + : this(score, new Room + { + RoomID = { Value = 1 }, + Name = { Value = "an awesome room" } + }) { } @@ -76,12 +80,12 @@ namespace osu.Game.Tests.Visual this.room = room; } - public override ResultsPage CreatePage() => new TestRoomRankingResultsPage(score, beatmap, room); + public override ResultsPage CreatePage() => new TestRoomLeaderboardPage(score, beatmap, room); } - private class TestRoomRankingResultsPage : RoomRankingResultsPage + private class TestRoomLeaderboardPage : RoomLeaderboardPage { - public TestRoomRankingResultsPage(ScoreInfo score, WorkingBeatmap beatmap, Room room) + public TestRoomLeaderboardPage(ScoreInfo score, WorkingBeatmap beatmap, Room room) : base(score, beatmap, room) { } @@ -89,7 +93,7 @@ namespace osu.Game.Tests.Visual protected override MatchLeaderboard CreateLeaderboard(Room room) => new TestMatchLeaderboard(room); } - private class TestMatchLeaderboard : MatchLeaderboard + private class TestMatchLeaderboard : RoomLeaderboardPage.ResultsMatchLeaderboard { public TestMatchLeaderboard(Room room) : base(room) diff --git a/osu.Game.Tests/Visual/TestCaseResults.cs b/osu.Game.Tests/Visual/TestCaseResults.cs index a954c6c57c..98aaa23beb 100644 --- a/osu.Game.Tests/Visual/TestCaseResults.cs +++ b/osu.Game.Tests/Visual/TestCaseResults.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual typeof(Results), typeof(ResultsPage), typeof(ScoreResultsPage), - typeof(RankingResultsPage) + typeof(LocalLeaderboardPage) }; [BackgroundDependencyLoader] diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index d9d78245bb..a30a3c4254 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Online.Leaderboards { - public abstract class Leaderboard : Container + public abstract class Leaderboard : Container, IOnlineComponent { private const double fade_duration = 300; @@ -55,14 +55,8 @@ namespace osu.Game.Online.Leaderboards // ensure placeholder is hidden when displaying scores PlaceholderState = PlaceholderState.Successful; - var flow = scrollFlow = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(0f, 5f), - Padding = new MarginPadding { Top = 10, Bottom = 5 }, - ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1)) - }; + scrollFlow = CreateScoreFlow(); + scrollFlow.ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1)); // schedule because we may not be loaded yet (LoadComponentAsync complains). showScoresDelegate?.Cancel(); @@ -71,12 +65,12 @@ namespace osu.Game.Online.Leaderboards else showScores(); - void showScores() => LoadComponentAsync(flow, _ => + void showScores() => LoadComponentAsync(scrollFlow, _ => { - scrollContainer.Add(flow); + scrollContainer.Add(scrollFlow); int i = 0; - foreach (var s in flow.Children) + foreach (var s in scrollFlow.Children) { using (s.BeginDelayedSequence(i++ * 50, true)) s.Show(); @@ -87,6 +81,16 @@ namespace osu.Game.Online.Leaderboards } } + protected virtual FillFlowContainer CreateScoreFlow() + => new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(0f, 5f), + Padding = new MarginPadding { Top = 10, Bottom = 5 }, + + }; + private TScope scope; public TScope Scope @@ -175,26 +179,22 @@ namespace osu.Game.Online.Leaderboards private void load(APIAccess api) { this.api = api; - - if (api != null) - api.OnStateChange += handleApiStateChange; + api?.Register(this); } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - - if (api != null) - api.OnStateChange -= handleApiStateChange; + api?.Unregister(this); } public void RefreshScores() => UpdateScores(); private APIRequest getScoresRequest; - private void handleApiStateChange(APIState oldState, APIState newState) + public void APIStateChanged(APIAccess api, APIState state) { - if (newState == APIState.Online) + if (state == APIState.Online) UpdateScores(); } @@ -265,14 +265,18 @@ namespace osu.Game.Online.Leaderboards currentPlaceholder = placeholder; } + protected virtual bool FadeBottom => true; + protected virtual bool FadeTop => true; + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); - var fadeStart = scrollContainer.Current + scrollContainer.DrawHeight; + var fadeBottom = scrollContainer.Current + scrollContainer.DrawHeight; + var fadeTop = scrollContainer.Current + LeaderboardScore.HEIGHT; if (!scrollContainer.IsScrolledToEnd()) - fadeStart -= LeaderboardScore.HEIGHT; + fadeBottom -= LeaderboardScore.HEIGHT; if (scrollFlow == null) return; @@ -282,15 +286,23 @@ namespace osu.Game.Online.Leaderboards var topY = c.ToSpaceOfOtherDrawable(Vector2.Zero, scrollFlow).Y; var bottomY = topY + LeaderboardScore.HEIGHT; - if (bottomY < fadeStart) + bool requireTopFade = FadeTop && topY <= fadeTop; + bool requireBottomFade = FadeBottom && bottomY >= fadeBottom; + + if (!requireTopFade && !requireBottomFade) c.Colour = Color4.White; - else if (topY > fadeStart + LeaderboardScore.HEIGHT) + else if (topY > fadeBottom + LeaderboardScore.HEIGHT || bottomY < fadeTop - LeaderboardScore.HEIGHT) c.Colour = Color4.Transparent; else { - c.Colour = ColourInfo.GradientVertical( - Color4.White.Opacity(Math.Min(1 - (topY - fadeStart) / LeaderboardScore.HEIGHT, 1)), - Color4.White.Opacity(Math.Min(1 - (bottomY - fadeStart) / LeaderboardScore.HEIGHT, 1))); + if (bottomY - fadeBottom > 0 && FadeBottom) + c.Colour = ColourInfo.GradientVertical( + Color4.White.Opacity(Math.Min(1 - (topY - fadeBottom) / LeaderboardScore.HEIGHT, 1)), + Color4.White.Opacity(Math.Min(1 - (bottomY - fadeBottom) / LeaderboardScore.HEIGHT, 1))); + else if (FadeTop) + c.Colour = ColourInfo.GradientVertical( + Color4.White.Opacity(Math.Min(1 - (fadeTop - topY) / LeaderboardScore.HEIGHT, 1)), + Color4.White.Opacity(Math.Min(1 - (fadeTop - bottomY) / LeaderboardScore.HEIGHT, 1))); } } } diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index 0c64105d5c..e60a73467b 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -73,8 +73,8 @@ namespace osu.Game.Online.Leaderboards { new OsuSpriteText { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Font = @"Exo2.0-MediumItalic", TextSize = 22, // ReSharper disable once ImpureMethodCallOnReadonlyValueField diff --git a/osu.Game/Screens/Multi/Ranking/MatchResults.cs b/osu.Game/Screens/Multi/Ranking/MatchResults.cs index c0544540c4..018eb60564 100644 --- a/osu.Game/Screens/Multi/Ranking/MatchResults.cs +++ b/osu.Game/Screens/Multi/Ranking/MatchResults.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Multi.Ranking protected override IEnumerable CreateResultPages() => new IResultPageInfo[] { new ScoreOverviewPageInfo(Score, Beatmap), - new BeatmapLeaderboardPageInfo(Score, Beatmap), + new LocalLeaderboardPageInfo(Score, Beatmap), new RoomLeaderboardPageInfo(Score, Beatmap, room), }; } diff --git a/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs similarity index 61% rename from osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs rename to osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs index a3836ed82a..8423a76a36 100644 --- a/osu.Game/Screens/Multi/Ranking/Pages/RoomRankingResultsPage.cs +++ b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs @@ -13,6 +13,7 @@ using osu.Framework.Lists; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Leaderboards; using osu.Game.Online.Multiplayer; using osu.Game.Scoring; using osu.Game.Screens.Multi.Match.Components; @@ -20,7 +21,7 @@ using osu.Game.Screens.Ranking; namespace osu.Game.Screens.Multi.Ranking.Pages { - public class RoomRankingResultsPage : ResultsPage + public class RoomLeaderboardPage : ResultsPage { private readonly Room room; @@ -28,7 +29,7 @@ namespace osu.Game.Screens.Multi.Ranking.Pages private TextFlowContainer rankText; - public RoomRankingResultsPage(ScoreInfo score, WorkingBeatmap beatmap, Room room) + public RoomLeaderboardPage(ScoreInfo score, WorkingBeatmap beatmap, Room room) : base(score, beatmap) { this.room = room; @@ -45,13 +46,13 @@ namespace osu.Game.Screens.Multi.Ranking.Pages { new Box { - Colour = colours.GrayE, + Colour = colours.Gray6, RelativeSizeAxes = Axes.Both, }, new BufferedContainer { RelativeSizeAxes = Axes.Both, - BackgroundColour = colours.GrayE, + BackgroundColour = colours.Gray6, Child = leaderboard = CreateLeaderboard(room) }, rankText = new TextFlowContainer @@ -61,7 +62,7 @@ namespace osu.Game.Screens.Multi.Ranking.Pages RelativeSizeAxes = Axes.X, Width = 0.5f, AutoSizeAxes = Axes.Y, - Y = 75, + Y = 50, TextAnchor = Anchor.TopCentre }, }; @@ -70,14 +71,20 @@ namespace osu.Game.Screens.Multi.Ranking.Pages leaderboard.Anchor = Anchor.Centre; leaderboard.RelativeSizeAxes = Axes.Both; leaderboard.Height = 0.8f; - leaderboard.Y = 95; + leaderboard.Y = 55; leaderboard.ScoresLoaded = scoresLoaded; } private void scoresLoaded(IEnumerable scores) { - Action gray = s => s.Colour = colours.Gray8; + Action gray = s => s.Colour = colours.GrayC; + Action white = s => + { + s.TextSize *= 1.4f; + s.Colour = colours.GrayF; + }; + rankText.AddText(room.Name + "\n", white); rankText.AddText("You are placed ", gray); int index = scores.IndexOf(new APIRoomScoreInfo { User = Score.User }, new FuncEqualityComparer((s1, s2) => s1.User.Id.Equals(s2.User.Id))); @@ -91,6 +98,42 @@ namespace osu.Game.Screens.Multi.Ranking.Pages rankText.AddText("in the room!", gray); } - protected virtual MatchLeaderboard CreateLeaderboard(Room room) => new MatchLeaderboard(room); + protected virtual MatchLeaderboard CreateLeaderboard(Room room) => new ResultsMatchLeaderboard(room); + + public class ResultsMatchLeaderboard : MatchLeaderboard + { + public ResultsMatchLeaderboard(Room room) + : base(room) + { + } + + protected override LeaderboardScore CreateDrawableScore(APIRoomScoreInfo model, int index) + => new ResultsMatchLeaderboardScore(model, index); + + protected override FillFlowContainer CreateScoreFlow() + { + var flow = base.CreateScoreFlow(); + flow.Padding = new MarginPadding + { + Top = LeaderboardScore.HEIGHT * 2, + Bottom = LeaderboardScore.HEIGHT * 3, + }; + return flow; + } + + private class ResultsMatchLeaderboardScore : MatchLeaderboardScore + { + public ResultsMatchLeaderboardScore(APIRoomScoreInfo score, int rank) + : base(score, rank) + { + } + + [BackgroundDependencyLoader] + private void load() + { + } + + } + } } } diff --git a/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs b/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs index 07429b0b89..bc78210484 100644 --- a/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs +++ b/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs @@ -23,10 +23,10 @@ namespace osu.Game.Screens.Multi.Ranking.Types this.room = room; } - public FontAwesome Icon => FontAwesome.fa_list; + public FontAwesome Icon => FontAwesome.fa_users; public string Name => "Room Leaderboard"; - public virtual ResultsPage CreatePage() => new RoomRankingResultsPage(score, beatmap, room); + public virtual ResultsPage CreatePage() => new RoomLeaderboardPage(score, beatmap, room); } } diff --git a/osu.Game/Screens/Play/SoloResults.cs b/osu.Game/Screens/Play/SoloResults.cs index 5e318e95d1..c06a5c3f68 100644 --- a/osu.Game/Screens/Play/SoloResults.cs +++ b/osu.Game/Screens/Play/SoloResults.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Play protected override IEnumerable CreateResultPages() => new IResultPageInfo[] { new ScoreOverviewPageInfo(Score, Beatmap), - new BeatmapLeaderboardPageInfo(Score, Beatmap) + new LocalLeaderboardPageInfo(Score, Beatmap) }; } } diff --git a/osu.Game/Screens/Ranking/Pages/RankingResultsPage.cs b/osu.Game/Screens/Ranking/Pages/LocalLeaderboardPage.cs similarity index 85% rename from osu.Game/Screens/Ranking/Pages/RankingResultsPage.cs rename to osu.Game/Screens/Ranking/Pages/LocalLeaderboardPage.cs index 4c98e476c4..8ab45f2f1f 100644 --- a/osu.Game/Screens/Ranking/Pages/RankingResultsPage.cs +++ b/osu.Game/Screens/Ranking/Pages/LocalLeaderboardPage.cs @@ -12,9 +12,9 @@ using osuTK; namespace osu.Game.Screens.Ranking.Pages { - public class RankingResultsPage : ResultsPage + public class LocalLeaderboardPage : ResultsPage { - public RankingResultsPage(ScoreInfo score, WorkingBeatmap beatmap = null) + public LocalLeaderboardPage(ScoreInfo score, WorkingBeatmap beatmap = null) : base(score, beatmap) { } @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Ranking.Pages { new Box { - Colour = colours.GrayE, + Colour = colours.Gray6, RelativeSizeAxes = Axes.Both, }, new BeatmapLeaderboard diff --git a/osu.Game/Screens/Ranking/Types/BeatmapLeaderboardPageInfo.cs b/osu.Game/Screens/Ranking/Types/LocalLeaderboardPageInfo.cs similarity index 59% rename from osu.Game/Screens/Ranking/Types/BeatmapLeaderboardPageInfo.cs rename to osu.Game/Screens/Ranking/Types/LocalLeaderboardPageInfo.cs index 2b192d4bcd..20eb75ff6f 100644 --- a/osu.Game/Screens/Ranking/Types/BeatmapLeaderboardPageInfo.cs +++ b/osu.Game/Screens/Ranking/Types/LocalLeaderboardPageInfo.cs @@ -8,21 +8,21 @@ using osu.Game.Screens.Ranking.Pages; namespace osu.Game.Screens.Ranking.Types { - public class BeatmapLeaderboardPageInfo : IResultPageInfo + public class LocalLeaderboardPageInfo : IResultPageInfo { private readonly ScoreInfo score; private readonly WorkingBeatmap beatmap; - public BeatmapLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap) + public LocalLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap) { this.score = score; this.beatmap = beatmap; } - public FontAwesome Icon => FontAwesome.fa_list; + public FontAwesome Icon => FontAwesome.fa_user; - public string Name => @"Beatmap Leaderboard"; + public string Name => @"Local Leaderboard"; - public ResultsPage CreatePage() => new RankingResultsPage(score, beatmap); + public ResultsPage CreatePage() => new LocalLeaderboardPage(score, beatmap); } } diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 9f8726c86a..29ed7fe4dc 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -36,6 +36,8 @@ namespace osu.Game.Screens.Select.Leaderboards } } + protected override bool FadeTop => false; + [Resolved] private ScoreManager scoreManager { get; set; } From a3b6a3981c04c522d18b915b976916f066460149 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 16:14:30 +0900 Subject: [PATCH 180/220] Use .Equals() override instead of manual type checks --- osu.Game/Online/Multiplayer/Room.cs | 9 ++------- osu.Game/Online/Multiplayer/RoomStatus.cs | 3 +++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 80558b14db..5cf73b5617 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -88,14 +88,9 @@ namespace osu.Game.Online.Multiplayer if (other.Host.Value != null && Host.Value?.Id != other.Host.Value.Id) Host.Value = other.Host; - if (Status.Value.GetType() != other.Status.Value.GetType()) - Status.Value = other.Status; - + Status.Value = other.Status; Availability.Value = other.Availability; - - if (Type.Value.GetType() != other.Type.Value.GetType()) - Type.Value = other.Type; - + Type.Value = other.Type; MaxParticipants.Value = other.MaxParticipants; ParticipantCount.Value = other.ParticipantCount.Value; Participants.Value = other.Participants.Value.ToArray(); diff --git a/osu.Game/Online/Multiplayer/RoomStatus.cs b/osu.Game/Online/Multiplayer/RoomStatus.cs index e2d84500a9..f5c339c71f 100644 --- a/osu.Game/Online/Multiplayer/RoomStatus.cs +++ b/osu.Game/Online/Multiplayer/RoomStatus.cs @@ -10,5 +10,8 @@ namespace osu.Game.Online.Multiplayer { public abstract string Message { get; } public abstract Color4 GetAppropriateColour(OsuColour colours); + + public override int GetHashCode() => GetType().GetHashCode(); + public override bool Equals(object obj) => GetType() == obj?.GetType(); } } From 50201e602eacbdc1a03c99f405c96734e2ab99ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 16:18:48 +0900 Subject: [PATCH 181/220] Combine implementations of status + end date info --- .../Screens/Multi/Components/EndDateInfo.cs | 32 ----- .../Multi/Components/RoomStatusInfo.cs | 111 ++++++++++++++++++ .../Multi/Lounge/Components/DrawableRoom.cs | 33 +----- .../Screens/Multi/Match/Components/Info.cs | 48 ++------ 4 files changed, 122 insertions(+), 102 deletions(-) delete mode 100644 osu.Game/Screens/Multi/Components/EndDateInfo.cs create mode 100644 osu.Game/Screens/Multi/Components/RoomStatusInfo.cs diff --git a/osu.Game/Screens/Multi/Components/EndDateInfo.cs b/osu.Game/Screens/Multi/Components/EndDateInfo.cs deleted file mode 100644 index c71ec04d33..0000000000 --- a/osu.Game/Screens/Multi/Components/EndDateInfo.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using osu.Game.Graphics; - -namespace osu.Game.Screens.Multi.Components -{ - public class EndDateInfo : DrawableDate - { - public EndDateInfo() - : base(DateTimeOffset.UtcNow) - { - } - - protected override string Format() - { - var diffToNow = Date.Subtract(DateTimeOffset.Now); - - if (diffToNow.TotalSeconds < -5) - return $"Closed {base.Format()}"; - - if (diffToNow.TotalSeconds < 0) - return "Closed"; - - if (diffToNow.TotalSeconds < 5) - return "Closing soon"; - - return $"Closing {base.Format()}"; - } - } -} diff --git a/osu.Game/Screens/Multi/Components/RoomStatusInfo.cs b/osu.Game/Screens/Multi/Components/RoomStatusInfo.cs new file mode 100644 index 0000000000..ca93ea2366 --- /dev/null +++ b/osu.Game/Screens/Multi/Components/RoomStatusInfo.cs @@ -0,0 +1,111 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Online.Multiplayer; +using osu.Game.Online.Multiplayer.RoomStatuses; + +namespace osu.Game.Screens.Multi.Components +{ + public class RoomStatusInfo : CompositeDrawable + { + private readonly RoomBindings bindings = new RoomBindings(); + + public RoomStatusInfo(Room room) + { + bindings.Room = room; + + AutoSizeAxes = Axes.Both; + + StatusPart statusPart; + EndDatePart endDatePart; + + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + statusPart = new StatusPart + { + TextSize = 14, + Font = "Exo2.0-Bold" + }, + endDatePart = new EndDatePart { TextSize = 14 } + } + }; + + statusPart.EndDate.BindTo(bindings.EndDate); + statusPart.Status.BindTo(bindings.Status); + statusPart.Availability.BindTo(bindings.Availability); + endDatePart.EndDate.BindTo(bindings.EndDate); + } + + private class EndDatePart : DrawableDate + { + public readonly IBindable EndDate = new Bindable(); + + public EndDatePart() + : base(DateTimeOffset.UtcNow) + { + EndDate.BindValueChanged(d => Date = d); + } + + protected override string Format() + { + var diffToNow = Date.Subtract(DateTimeOffset.Now); + + if (diffToNow.TotalSeconds < -5) + return $"Closed {base.Format()}"; + + if (diffToNow.TotalSeconds < 0) + return "Closed"; + + if (diffToNow.TotalSeconds < 5) + return "Closing soon"; + + return $"Closing {base.Format()}"; + } + } + + private class StatusPart : EndDatePart + { + public readonly IBindable Status = new Bindable(); + public readonly IBindable Availability = new Bindable(); + + [Resolved] + private OsuColour colours { get; set; } + + public StatusPart() + { + EndDate.BindValueChanged(_ => Format()); + Status.BindValueChanged(_ => Format()); + Availability.BindValueChanged(_ => Format()); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Text = Format(); + } + + protected override string Format() + { + if (!IsLoaded) + return string.Empty; + + RoomStatus status = Date < DateTimeOffset.Now ? new RoomStatusEnded() : Status.Value ?? new RoomStatusOpen(); + + this.FadeColour(status.GetAppropriateColour(colours), 100); + return $"{Availability.Value.GetDescription()}, {status.Message}"; + } + } + } +} diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index 0540eed1aa..fb31864cc5 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -99,10 +99,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components private void load(OsuColour colours) { Box sideStrip; - OsuSpriteText status; ParticipantInfo participantInfo; OsuSpriteText name; - EndDateInfo endDate; Children = new Drawable[] { @@ -172,31 +170,11 @@ namespace osu.Game.Screens.Multi.Lounge.Components RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), Children = new Drawable[] { - status = new OsuSpriteText - { - TextSize = 14, - Font = @"Exo2.0-Bold", - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 5), - Children = new Drawable[] - { - endDate = new EndDateInfo - { - TextSize = 14, - }, - beatmapTitle = new BeatmapTitle - { - TextSize = 14, - }, - } - } + new RoomStatusInfo(Room), + beatmapTitle = new BeatmapTitle { TextSize = 14 }, }, }, modeTypeInfo = new ModeTypeInfo @@ -220,12 +198,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components participantInfo.ParticipantCount.BindTo(bindings.ParticipantCount); bindings.Name.BindValueChanged(n => name.Text = n, true); - bindings.EndDate.BindValueChanged(d => endDate.Date = d, true); bindings.Status.BindValueChanged(s => { - status.Text = s.Message; - - foreach (Drawable d in new Drawable[] { selectionBox, sideStrip, status }) + foreach (Drawable d in new Drawable[] { selectionBox, sideStrip }) d.FadeColour(s.GetAppropriateColour(colours), transition_duration); }, true); } diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index 08ba370282..0aabc014c9 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using osu.Framework.Allocation; -using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -20,10 +18,6 @@ namespace osu.Game.Screens.Multi.Match.Components { public Action OnStart; - private readonly OsuSpriteText availabilityStatus; - - private OsuColour colours; - private readonly RoomBindings bindings = new RoomBindings(); public Info(Room room) @@ -33,9 +27,8 @@ namespace osu.Game.Screens.Multi.Match.Components ReadyButton readyButton; ViewBeatmapButton viewBeatmapButton; - OsuSpriteText name; - EndDateInfo endDate; HostInfo hostInfo; + RoomStatusInfo statusInfo; Children = new Drawable[] { @@ -65,9 +58,12 @@ namespace osu.Game.Screens.Multi.Match.Components Direction = FillDirection.Vertical, Children = new Drawable[] { - name = new OsuSpriteText { TextSize = 30 }, - availabilityStatus = new OsuSpriteText { TextSize = 14 }, - endDate = new EndDateInfo { TextSize = 14 } + new OsuSpriteText + { + TextSize = 30, + Current = bindings.Name + }, + new RoomStatusInfo(room), } }, hostInfo = new HostInfo(), @@ -98,37 +94,7 @@ namespace osu.Game.Screens.Multi.Match.Components readyButton.Beatmap.BindTo(bindings.CurrentBeatmap); hostInfo.Host.BindTo(bindings.Host); - bindings.Availability.BindValueChanged(_ => updateAvailabilityStatus()); - bindings.Status.BindValueChanged(_ => updateAvailabilityStatus()); - bindings.Name.BindValueChanged(n => name.Text = n); - bindings.EndDate.BindValueChanged(d => endDate.Date = d); - bindings.Room = room; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - this.colours = colours; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - updateAvailabilityStatus(); - } - - private void updateAvailabilityStatus() - { - if (!IsLoaded) - return; - - if (bindings.Status.Value != null) - { - availabilityStatus.FadeColour(bindings.Status.Value.GetAppropriateColour(colours), 100); - availabilityStatus.Text = $"{bindings.Availability.Value.GetDescription()}, {bindings.Status.Value.Message}"; - } - } } } From c614505b7cf39540ea539522ddcaf24c2e96d421 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 16:20:37 +0900 Subject: [PATCH 182/220] Revert unnecessary change to testcase --- osu.Game.Tests/Visual/TestCasePollingComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCasePollingComponent.cs b/osu.Game.Tests/Visual/TestCasePollingComponent.cs index 3f999f2b89..b4b9d465e5 100644 --- a/osu.Game.Tests/Visual/TestCasePollingComponent.cs +++ b/osu.Game.Tests/Visual/TestCasePollingComponent.cs @@ -122,7 +122,7 @@ namespace osu.Game.Tests.Visual }; }); - protected override double TimePerAction => 5000; + protected override double TimePerAction => 500; public class TestPoller : PollingComponent { From 8e031325dd1a4904a503be2760fb3c5f53bc9b22 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 16:28:17 +0900 Subject: [PATCH 183/220] CI fixes --- osu.Game/Online/Leaderboards/Leaderboard.cs | 1 - .../Multiplayer/GameTypes/GameTypeTag.cs | 5 ++- .../Multiplayer/GameTypes/GameTypeTagTeam.cs | 5 ++- .../GameTypes/GameTypeTeamVersus.cs | 5 ++- .../GameTypes/GameTypeTimeshift.cs | 3 ++ .../Multiplayer/GameTypes/GameTypeVersus.cs | 5 ++- .../Online/Multiplayer/GameTypes/VersusRow.cs | 5 ++- osu.Game/Online/Multiplayer/Room.cs | 1 - .../Multi/Match/Components/HostInfo.cs | 2 -- .../Match/Components/MatchLeaderboard.cs | 23 ------------- .../Match/Components/MatchLeaderboardScore.cs | 33 +++++++++++++++++++ .../Match/Components/MatchSettingsOverlay.cs | 1 - .../Ranking/Pages/RoomLeaderboardPage.cs | 1 - osu.Game/Screens/Multi/RoomManager.cs | 1 - 14 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index a30a3c4254..0c61491f9d 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -88,7 +88,6 @@ namespace osu.Game.Online.Leaderboards AutoSizeAxes = Axes.Y, Spacing = new Vector2(0f, 5f), Padding = new MarginPadding { Top = 10, Bottom = 5 }, - }; private TScope scope; diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs index d31439f0fe..c9d16662ba 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using osu.Framework.Graphics; using osu.Game.Graphics; using osuTK; @@ -21,4 +24,4 @@ namespace osu.Game.Online.Multiplayer.GameTypes }; } } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs index 74c8e76b46..952d1a39ac 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -38,4 +41,4 @@ namespace osu.Game.Online.Multiplayer.GameTypes }; } } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs index 74c2c00c3b..49e7cef88d 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -26,4 +29,4 @@ namespace osu.Game.Online.Multiplayer.GameTypes }; } } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs index e87f8a9696..ab8658dfb2 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using osu.Framework.Graphics; using osu.Game.Graphics; using osuTK; diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs index b6d832490f..c74ce63470 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using osu.Framework.Graphics; using osu.Game.Graphics; @@ -16,4 +19,4 @@ namespace osu.Game.Online.Multiplayer.GameTypes }; } } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Multiplayer/GameTypes/VersusRow.cs b/osu.Game/Online/Multiplayer/GameTypes/VersusRow.cs index 2b150fc6f0..b4d8279d02 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/VersusRow.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/VersusRow.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -49,4 +52,4 @@ namespace osu.Game.Online.Multiplayer.GameTypes }; } } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 5cf73b5617..0d6a8ae3a8 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -50,7 +50,6 @@ namespace osu.Game.Online.Multiplayer [JsonIgnore] public Bindable> Participants { get; private set; } = new Bindable>(Enumerable.Empty()); - public Bindable ParticipantCount { get; private set; } = new Bindable(); // todo: TEMPORARY diff --git a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs index 437b4cfe1b..993dccce44 100644 --- a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs +++ b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs @@ -42,8 +42,6 @@ namespace osu.Game.Screens.Multi.Match.Components } }; - - Host.BindValueChanged(updateHost); } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index dd5a73817f..864191105f 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -4,13 +4,11 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Game.Graphics; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Online.Multiplayer; -using osu.Game.Scoring; namespace osu.Game.Screens.Multi.Match.Components { @@ -57,27 +55,6 @@ namespace osu.Game.Screens.Multi.Match.Components protected override LeaderboardScore CreateDrawableScore(APIRoomScoreInfo model, int index) => new MatchLeaderboardScore(model, index); } - public class MatchLeaderboardScore : LeaderboardScore - { - public MatchLeaderboardScore(APIRoomScoreInfo score, int rank) - : base(score, rank) - { - } - - [BackgroundDependencyLoader] - private void load() - { - RankContainer.Alpha = 0; - } - - protected override IEnumerable GetStatistics(ScoreInfo model) => new[] - { - new LeaderboardScoreStatistic(FontAwesome.fa_crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)), - new LeaderboardScoreStatistic(FontAwesome.fa_refresh, "Total Attempts", ((APIRoomScoreInfo)model).TotalAttempts.ToString()), - new LeaderboardScoreStatistic(FontAwesome.fa_check, "Completed Beatmaps", ((APIRoomScoreInfo)model).CompletedBeatmaps.ToString()), - }; - } - public enum MatchLeaderboardScope { Overall diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs new file mode 100644 index 0000000000..ebd69b24fc --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Game.Graphics; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Leaderboards; +using osu.Game.Scoring; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class MatchLeaderboardScore : LeaderboardScore + { + public MatchLeaderboardScore(APIRoomScoreInfo score, int rank) + : base(score, rank) + { + } + + [BackgroundDependencyLoader] + private void load() + { + RankContainer.Alpha = 0; + } + + protected override IEnumerable GetStatistics(ScoreInfo model) => new[] + { + new LeaderboardScoreStatistic(FontAwesome.fa_crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)), + new LeaderboardScoreStatistic(FontAwesome.fa_refresh, "Total Attempts", ((APIRoomScoreInfo)model).TotalAttempts.ToString()), + new LeaderboardScoreStatistic(FontAwesome.fa_check, "Completed Beatmaps", ((APIRoomScoreInfo)model).CompletedBeatmaps.ToString()), + }; + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 5d16f0f8cd..1210b9379f 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -294,7 +294,6 @@ namespace osu.Game.Screens.Multi.Match.Components bindings.Duration.Value = DurationField.Current.Value; - manager?.CreateRoom(room, onSuccess, onError); processingOverlay.Show(); diff --git a/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs index 8423a76a36..3673944837 100644 --- a/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs +++ b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs @@ -132,7 +132,6 @@ namespace osu.Game.Screens.Multi.Ranking.Pages private void load() { } - } } } diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index ceecaf5443..6810fdebe9 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -40,7 +40,6 @@ namespace osu.Game.Screens.Multi TimeBetweenPolls = 5000; } - protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From f70e60747f1be3f13c0f0c3993bc8ee412801dfc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 16:54:14 +0900 Subject: [PATCH 184/220] Remove option for 1-minute duration --- osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 1210b9379f..72136b1874 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -157,7 +157,6 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.X, Items = new[] { - TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(30), TimeSpan.FromHours(1), TimeSpan.FromHours(2), From bd0576537e27cb7343165dc747861d461df06b1f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 17:12:47 +0900 Subject: [PATCH 185/220] Forcefully exit multiplayer if API loses connectivity --- osu.Game/Screens/Multi/Multiplayer.cs | 32 ++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 499198d800..eb6acdd551 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Screens.Multi { [Cached] - public class Multiplayer : OsuScreen + public class Multiplayer : OsuScreen, IOnlineComponent { private readonly MultiplayerWaveContainer waves; @@ -98,6 +98,30 @@ namespace osu.Game.Screens.Multi loungeSubScreen.Exited += _ => Exit(); } + [BackgroundDependencyLoader] + private void load() + { + api.Register(this); + } + + public void APIStateChanged(APIAccess api, APIState state) + { + if (state != APIState.Online) + forcefullyExit(); + } + + private void forcefullyExit() + { + // This is temporary since we don't currently have a way to force screens to be exited + if (IsCurrentScreen) + Exit(); + else + { + MakeCurrent(); + Schedule(forcefullyExit); + } + } + protected override void OnEntering(Screen last) { Content.FadeIn(); @@ -196,6 +220,12 @@ namespace osu.Game.Screens.Multi currentScreen = (OsuScreen)newScreen; } + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + api?.Unregister(this); + } + private class MultiplayerWaveContainer : WaveContainer { protected override bool StartHidden => true; From ea1309e76883481d95b5d60b70311abf696d727e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 17:15:43 +0900 Subject: [PATCH 186/220] Fix missing bind --- osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index a7fa592323..47f915b739 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -171,6 +171,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components participantInfo.Participants.BindTo(bindings.Participants); participantCount.Participants.BindTo(bindings.Participants); + participantCount.ParticipantCount.BindTo(bindings.ParticipantCount); participantCount.MaxParticipants.BindTo(bindings.MaxParticipants); beatmapTypeInfo.Type.BindTo(bindings.Type); From dae710f9a655a0a48bdda63b5756365bfb0cf3b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 17:29:55 +0900 Subject: [PATCH 187/220] Make leaderboard top not fade by default --- osu.Game/Online/Leaderboards/Leaderboard.cs | 2 +- osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs | 2 ++ osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 2 -- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 0c61491f9d..f3bf16a05f 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -265,7 +265,7 @@ namespace osu.Game.Online.Leaderboards } protected virtual bool FadeBottom => true; - protected virtual bool FadeTop => true; + protected virtual bool FadeTop => false; protected override void UpdateAfterChildren() { diff --git a/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs index 3673944837..54528e5503 100644 --- a/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs +++ b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs @@ -107,6 +107,8 @@ namespace osu.Game.Screens.Multi.Ranking.Pages { } + protected override bool FadeTop => true; + protected override LeaderboardScore CreateDrawableScore(APIRoomScoreInfo model, int index) => new ResultsMatchLeaderboardScore(model, index); diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 29ed7fe4dc..9f8726c86a 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -36,8 +36,6 @@ namespace osu.Game.Screens.Select.Leaderboards } } - protected override bool FadeTop => false; - [Resolved] private ScoreManager scoreManager { get; set; } From b0e8561ad35940b82459710ceb30d783330396eb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 17:48:10 +0900 Subject: [PATCH 188/220] Fix ruleset not changing correctly --- osu.Game/Screens/Multi/RoomBindings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/RoomBindings.cs b/osu.Game/Screens/Multi/RoomBindings.cs index 9a38ba1f60..dc2547268d 100644 --- a/osu.Game/Screens/Multi/RoomBindings.cs +++ b/osu.Game/Screens/Multi/RoomBindings.cs @@ -101,6 +101,6 @@ namespace osu.Game.Screens.Multi public IBindable> CurrentMods => currentMods; private readonly Bindable currentRuleset = new Bindable(); - public IBindable CurrentRuleset = new Bindable(); + public IBindable CurrentRuleset => currentRuleset; } } From d6c53e38510035e6734c7e793867376e082064cb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 18:09:42 +0900 Subject: [PATCH 189/220] Cancel old web requests when changing filter modes --- osu.Game/Screens/Multi/RoomManager.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 6810fdebe9..2ab756e92a 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -109,6 +109,8 @@ namespace osu.Game.Screens.Multi PollImmediately(); } + private GetRoomsRequest pollReq; + protected override Task Poll() { if (!api.IsLoggedIn) @@ -116,7 +118,8 @@ namespace osu.Game.Screens.Multi var tcs = new TaskCompletionSource(); - var pollReq = new GetRoomsRequest(currentFilter.PrimaryFilter); + pollReq?.Cancel(); + pollReq = new GetRoomsRequest(currentFilter.PrimaryFilter); pollReq.Success += result => { From 9a5630b3d5aff8665729543ebabe23553c452142 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 18:10:49 +0900 Subject: [PATCH 190/220] Fix working beatmap not being updated --- .../Screens/Multi/Match/MatchSubScreen.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 5cd5d9e76a..9ff1b84b41 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -119,6 +119,12 @@ namespace osu.Game.Screens.Multi.Match chat.Exit += Exit; } + [BackgroundDependencyLoader] + private void load() + { + beatmapManager.ItemAdded += beatmapAdded; + } + protected override bool OnExiting(Screen next) { manager?.PartRoom(); @@ -155,6 +161,21 @@ namespace osu.Game.Screens.Multi.Match game?.ForcefullySetRuleset(ruleset); } + private void beatmapAdded(BeatmapSetInfo model, bool existing, bool silent) => Schedule(() => + { + if (Beatmap.Value != beatmapManager.DefaultBeatmap) + return; + + if (bindings.CurrentBeatmap.Value == null) + return; + + // Try to retrieve the corresponding local beatmap + var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == bindings.CurrentBeatmap.Value.OnlineBeatmapID); + + if (localBeatmap != null) + game?.ForcefullySetBeatmap(beatmapManager.GetWorkingBeatmap(localBeatmap)); + }); + private void addPlaylistItem(PlaylistItem item) { bindings.Playlist.Clear(); @@ -176,5 +197,13 @@ namespace osu.Game.Screens.Multi.Match break; } } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (beatmapManager != null) + beatmapManager.ItemAdded -= beatmapAdded; + } } } From eaba9e13789e1287f0427a3a84786b1dd21de392 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 18:16:17 +0900 Subject: [PATCH 191/220] Fix mode icon not being updated for correct ruleset --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 10 ++++++---- osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs | 4 +++- osu.Game/Screens/Multi/Components/ModeTypeInfo.cs | 5 ++++- .../Screens/Multi/Lounge/Components/DrawableRoom.cs | 3 ++- .../Screens/Multi/Lounge/Components/RoomInspector.cs | 3 ++- osu.Game/Screens/Multi/Match/Components/Header.cs | 1 + 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 14162c35c0..fe6200472f 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; @@ -16,15 +17,16 @@ namespace osu.Game.Beatmaps.Drawables { public class DifficultyIcon : DifficultyColouredContainer { - private readonly BeatmapInfo beatmap; + private readonly RulesetInfo ruleset; - public DifficultyIcon(BeatmapInfo beatmap) + public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null) : base(beatmap) { if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); - this.beatmap = beatmap; + this.ruleset = ruleset ?? beatmap.Ruleset; + Size = new Vector2(20); } @@ -58,7 +60,7 @@ namespace osu.Game.Beatmaps.Drawables Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, // the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment) - Icon = beatmap.Ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o } + Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o } } }; } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs index a06eaa35dc..04ac0cc4c3 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.Chat; using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; using osuTK; namespace osu.Game.Screens.Multi.Components @@ -16,7 +17,7 @@ namespace osu.Game.Screens.Multi.Components public class BeatmapTypeInfo : CompositeDrawable { public readonly IBindable Beatmap = new Bindable(); - + public readonly IBindable Ruleset = new Bindable(); public readonly IBindable Type = new Bindable(); public BeatmapTypeInfo() @@ -56,6 +57,7 @@ namespace osu.Game.Screens.Multi.Components }; modeTypeInfo.Beatmap.BindTo(Beatmap); + modeTypeInfo.Ruleset.BindTo(Ruleset); modeTypeInfo.Type.BindTo(Type); beatmapTitle.Beatmap.BindTo(Beatmap); diff --git a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 8104244084..aad409e2c7 100644 --- a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; using osuTK; namespace osu.Game.Screens.Multi.Components @@ -19,6 +20,7 @@ namespace osu.Game.Screens.Multi.Components private readonly Container rulesetContainer; public readonly IBindable Beatmap = new Bindable(); + public readonly IBindable Ruleset = new Bindable(); public readonly IBindable Type = new Bindable(); public ModeTypeInfo() @@ -47,6 +49,7 @@ namespace osu.Game.Screens.Multi.Components }; Beatmap.BindValueChanged(updateBeatmap); + Ruleset.BindValueChanged(_ => updateBeatmap(Beatmap.Value)); Type.BindValueChanged(v => gameTypeContainer.Child = new DrawableGameType(v) { Size = new Vector2(height) }); } @@ -55,7 +58,7 @@ namespace osu.Game.Screens.Multi.Components if (beatmap != null) { rulesetContainer.FadeIn(transition_duration); - rulesetContainer.Child = new DifficultyIcon(beatmap) { Size = new Vector2(height) }; + rulesetContainer.Child = new DifficultyIcon(beatmap, Ruleset.Value) { Size = new Vector2(height) }; } else rulesetContainer.FadeOut(transition_duration); diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index fb31864cc5..219121cb53 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -191,8 +191,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components background.Beatmap.BindTo(bindings.CurrentBeatmap); modeTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); - beatmapTitle.Beatmap.BindTo(bindings.CurrentBeatmap); + modeTypeInfo.Ruleset.BindTo(bindings.CurrentRuleset); modeTypeInfo.Type.BindTo(bindings.Type); + beatmapTitle.Beatmap.BindTo(bindings.CurrentBeatmap); participantInfo.Host.BindTo(bindings.Host); participantInfo.Participants.BindTo(bindings.Participants); participantInfo.ParticipantCount.BindTo(bindings.ParticipantCount); diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 47f915b739..47f5182c39 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -174,9 +174,10 @@ namespace osu.Game.Screens.Multi.Lounge.Components participantCount.ParticipantCount.BindTo(bindings.ParticipantCount); participantCount.MaxParticipants.BindTo(bindings.MaxParticipants); + beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); + beatmapTypeInfo.Ruleset.BindTo(bindings.CurrentRuleset); beatmapTypeInfo.Type.BindTo(bindings.Type); background.Beatmap.BindTo(bindings.CurrentBeatmap); - beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); bindings.Status.BindValueChanged(displayStatus); bindings.Participants.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u))); diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 4f4d5a1d4e..4cb6d7a4e0 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -112,6 +112,7 @@ namespace osu.Game.Screens.Multi.Match.Components }; beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); + beatmapTypeInfo.Ruleset.BindTo(bindings.CurrentRuleset); beatmapTypeInfo.Type.BindTo(bindings.Type); background.Beatmap.BindTo(bindings.CurrentBeatmap); bindings.CurrentMods.BindValueChanged(m => modDisplay.Current.Value = m, true); From 31db768bdc44a46f6f34f5d2afdec09d27b78de9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 19:18:27 +0900 Subject: [PATCH 192/220] Hide version overlay when not in main menu --- osu.Game/OsuGame.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6a5f9656d1..cc923bb91f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -716,10 +716,16 @@ namespace osu.Game this.ruleset.Disabled = rulesetDisabled; } - private void screenAdded(Screen newScreen) + protected virtual void ScreenChanged(OsuScreen current, Screen newScreen) { currentScreen = (OsuScreen)newScreen; - Logger.Log($"Screen changed → {currentScreen}"); + } + + private void screenAdded(Screen newScreen) + { + ScreenChanged(currentScreen, newScreen); + Logger.Log($"Screen changed → {newScreen}"); + newScreen.ModePushed += screenAdded; newScreen.Exited += screenRemoved; @@ -727,7 +733,7 @@ namespace osu.Game private void screenRemoved(Screen newScreen) { - currentScreen = (OsuScreen)newScreen; + ScreenChanged(currentScreen, newScreen); Logger.Log($"Screen changed ← {currentScreen}"); if (newScreen == null) From bdadd1bba2b7e8e38c6fbe220296f75be94b3ed2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 19:22:24 +0900 Subject: [PATCH 193/220] Add actual changes --- osu.Desktop/Overlays/VersionManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index f31bba1e1e..c1fd34d009 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -128,11 +128,12 @@ namespace osu.Desktop.Overlays protected override void PopIn() { - this.FadeIn(1000); + this.FadeIn(1400, Easing.OutQuint); } protected override void PopOut() { + this.FadeOut(500, Easing.OutQuint); } } } From c6d017b503cd5ff8ab6d75f52995923ef5460826 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 19:23:58 +0900 Subject: [PATCH 194/220] And some more --- osu.Desktop/OsuGameDesktop.cs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 93fd3935c6..bd9ba3501f 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -15,12 +15,16 @@ using Microsoft.Win32; using osu.Desktop.Updater; using osu.Framework; using osu.Framework.Platform.Windows; +using osu.Framework.Screens; +using osu.Game.Screens; +using osu.Game.Screens.Menu; namespace osu.Desktop { internal class OsuGameDesktop : OsuGame { private readonly bool noVersionOverlay; + private VersionManager versionManager; public OsuGameDesktop(string[] args = null) : base(args) @@ -46,7 +50,7 @@ namespace osu.Desktop if (!noVersionOverlay) { - LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v => + LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, v => { Add(v); v.State = Visibility.Visible; @@ -59,6 +63,21 @@ namespace osu.Desktop } } + protected override void ScreenChanged(OsuScreen current, Screen newScreen) + { + base.ScreenChanged(current, newScreen); + switch (newScreen) + { + case Intro _: + case MainMenu _: + versionManager.State = Visibility.Visible; + break; + default: + versionManager.State = Visibility.Hidden; + break; + } + } + public override void SetHost(GameHost host) { base.SetHost(host); From ab5f6e149c82ebd2cd3ea8f2564df10c75efb991 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 19:25:56 +0900 Subject: [PATCH 195/220] Remvoe extra newline --- osu.Game/OsuGame.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index cc923bb91f..2a4c812401 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -726,7 +726,6 @@ namespace osu.Game ScreenChanged(currentScreen, newScreen); Logger.Log($"Screen changed → {newScreen}"); - newScreen.ModePushed += screenAdded; newScreen.Exited += screenRemoved; } From c5764ded1c26998cfdb917d566a0abd7ec65b50c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 20:03:32 +0900 Subject: [PATCH 196/220] Fix infinite polling rate in certain scenarios --- osu.Game/Online/PollingComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/PollingComponent.cs b/osu.Game/Online/PollingComponent.cs index 07b6db2dc2..36a42b5d0a 100644 --- a/osu.Game/Online/PollingComponent.cs +++ b/osu.Game/Online/PollingComponent.cs @@ -112,7 +112,7 @@ namespace osu.Game.Online pollingActive = false; if (scheduledPoll == null) - scheduleNextPoll(); + pollIfNecessary(); } private void scheduleNextPoll() From 1ce33cb6dac082911fefb5d3f3f0bd6a71996d20 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 20:06:07 +0900 Subject: [PATCH 197/220] Adjust polling rate based on current screen and idle state --- osu.Game/Screens/Multi/Multiplayer.cs | 45 ++++++++++++++++++++------- osu.Game/Screens/Multi/RoomManager.cs | 5 --- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index eb6acdd551..6b1c614ff6 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -2,14 +2,17 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Logging; using osu.Framework.Screens; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; +using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.BeatmapSet.Buttons; @@ -25,12 +28,12 @@ namespace osu.Game.Screens.Multi { private readonly MultiplayerWaveContainer waves; - public override bool AllowBeatmapRulesetChange => currentScreen?.AllowBeatmapRulesetChange ?? base.AllowBeatmapRulesetChange; + public override bool AllowBeatmapRulesetChange => currentSubScreen?.AllowBeatmapRulesetChange ?? base.AllowBeatmapRulesetChange; private readonly OsuButton createButton; private readonly LoungeSubScreen loungeSubScreen; - private OsuScreen currentScreen; + private OsuScreen currentSubScreen; [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; @@ -98,10 +101,25 @@ namespace osu.Game.Screens.Multi loungeSubScreen.Exited += _ => Exit(); } + private readonly IBindable isIdle = new BindableBool(); + [BackgroundDependencyLoader] - private void load() + private void load(IdleTracker idleTracker) { api.Register(this); + isIdle.BindTo(idleTracker.IsIdle); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + isIdle.BindValueChanged(updatePollingRate, true); + } + + private void updatePollingRate(bool idle) + { + roomManager.TimeBetweenPolls = !IsCurrentScreen || !(currentSubScreen is LoungeSubScreen) ? 0 : (idle ? 120000 : 15000); + Logger.Log($"Polling adjusted to {roomManager.TimeBetweenPolls}"); } public void APIStateChanged(APIAccess api, APIState state) @@ -136,11 +154,9 @@ namespace osu.Game.Screens.Multi Content.Delay(WaveContainer.DISAPPEAR_DURATION).FadeOut(); - var track = Beatmap.Value.Track; - if (track != null) - track.Looping = false; - + cancelLooping(); loungeSubScreen.MakeCurrent(); + updatePollingRate(isIdle.Value); return base.OnExiting(next); } @@ -151,6 +167,8 @@ namespace osu.Game.Screens.Multi Content.FadeIn(250); Content.ScaleTo(1, 250, Easing.OutSine); + + updatePollingRate(isIdle.Value); } protected override void OnSuspending(Screen next) @@ -159,6 +177,7 @@ namespace osu.Game.Screens.Multi Content.FadeOut(250); cancelLooping(); + roomManager.TimeBetweenPolls = 0; base.OnSuspending(next); } @@ -183,7 +202,7 @@ namespace osu.Game.Screens.Multi if (!IsCurrentScreen) return; - if (currentScreen is MatchSubScreen) + if (currentSubScreen is MatchSubScreen) { var track = Beatmap.Value.Track; if (track != null) @@ -200,13 +219,14 @@ namespace osu.Game.Screens.Multi createButton.Hide(); } - else if (currentScreen is LoungeSubScreen) + else if (currentSubScreen is LoungeSubScreen) createButton.Show(); } private void screenAdded(Screen newScreen) { - currentScreen = (OsuScreen)newScreen; + currentSubScreen = (OsuScreen)newScreen; + updatePollingRate(isIdle.Value); newScreen.ModePushed += screenAdded; newScreen.Exited += screenRemoved; @@ -214,10 +234,11 @@ namespace osu.Game.Screens.Multi private void screenRemoved(Screen newScreen) { - if (currentScreen is MatchSubScreen) + if (currentSubScreen is MatchSubScreen) cancelLooping(); - currentScreen = (OsuScreen)newScreen; + currentSubScreen = (OsuScreen)newScreen; + updatePollingRate(isIdle.Value); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 2ab756e92a..6fe2307d8b 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -35,11 +35,6 @@ namespace osu.Game.Screens.Multi [Resolved] private BeatmapManager beatmaps { get; set; } - public RoomManager() - { - TimeBetweenPolls = 5000; - } - protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From 4a4bc8955d717630c74d17deb6a6b0a13a8a29af Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 20:08:16 +0900 Subject: [PATCH 198/220] Fix crash on startup when specifying --no-version-overlay --- osu.Desktop/OsuGameDesktop.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index bd9ba3501f..2eeb112450 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -70,10 +70,12 @@ namespace osu.Desktop { case Intro _: case MainMenu _: - versionManager.State = Visibility.Visible; + if (versionManager != null) + versionManager.State = Visibility.Visible; break; default: - versionManager.State = Visibility.Hidden; + if (versionManager != null) + versionManager.State = Visibility.Hidden; break; } } From 31baf0086fa0096b07a4ce23c9464b3ee2c944ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 20:17:27 +0900 Subject: [PATCH 199/220] Optional idle tracker --- osu.Game/Screens/Multi/Multiplayer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 6b1c614ff6..ce0eddbee3 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -103,11 +103,13 @@ namespace osu.Game.Screens.Multi private readonly IBindable isIdle = new BindableBool(); - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(IdleTracker idleTracker) { api.Register(this); - isIdle.BindTo(idleTracker.IsIdle); + + if (idleTracker != null) + isIdle.BindTo(idleTracker.IsIdle); } protected override void LoadComplete() From 50b51a168e754fb4d4a243697c4a1fe72e95a37b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 21:12:32 +0900 Subject: [PATCH 200/220] Always submit standardised scores --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 18 +++++++++++++----- osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs | 11 +++++++++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 0ebea9c2d0..ebcf78435c 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -167,6 +167,8 @@ namespace osu.Game.Rulesets.Scoring score.Rank = Rank; score.Date = DateTimeOffset.Now; } + + public abstract double GetStandardisedScore(); } public class ScoreProcessor : ScoreProcessor @@ -340,18 +342,24 @@ namespace osu.Game.Rulesets.Scoring if (rollingMaxBaseScore != 0) Accuracy.Value = baseScore / rollingMaxBaseScore; - switch (Mode.Value) + TotalScore.Value = getScore(Mode.Value); + } + + private double getScore(ScoringMode mode) + { + switch (mode) { + default: case ScoringMode.Standardised: - TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore; - break; + return max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore; case ScoringMode.Classic: // should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1) - TotalScore.Value = bonusScore + baseScore * (1 + Math.Max(0, HighestCombo - 1) / 25); - break; + return bonusScore + baseScore * (1 + Math.Max(0, HighestCombo - 1) / 25); } } + public override double GetStandardisedScore() => getScore(ScoringMode.Standardised); + protected override void Reset(bool storeResults) { if (storeResults) diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index 0a7c11ecc5..84d0ca3621 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Diagnostics; using System.Threading; using osu.Framework.Allocation; @@ -60,16 +61,22 @@ namespace osu.Game.Screens.Multi.Play } protected override ScoreInfo CreateScore() + { + submitScore(); + return base.CreateScore(); + } + + private void submitScore() { var score = base.CreateScore(); + score.TotalScore = (int)Math.Round(ScoreProcessor.GetStandardisedScore()); + Debug.Assert(token != null); var request = new SubmitRoomScoreRequest(token.Value, room.RoomID.Value ?? 0, playlistItemId, score); request.Failure += e => Logger.Error(e, "Failed to submit score"); api.Queue(request); - - return score; } protected override Results CreateResults(ScoreInfo score) => new MatchResults(score, room); From fb10d158703c6bb25ba6f70899cb80083d2017d3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 21:52:09 +0900 Subject: [PATCH 201/220] Populate statistics for all rulesets' scores --- .../Scoring/OsuScoreProcessor.cs | 17 ----------------- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 9b3da1b8a8..7cd78c8be7 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -9,7 +9,6 @@ using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Scoring; namespace osu.Game.Rulesets.Osu.Scoring { @@ -22,7 +21,6 @@ namespace osu.Game.Rulesets.Osu.Scoring private float hpDrainRate; - private readonly Dictionary scoreResultCounts = new Dictionary(); private readonly Dictionary comboResultCounts = new Dictionary(); protected override void ApplyBeatmap(Beatmap beatmap) @@ -35,21 +33,9 @@ namespace osu.Game.Rulesets.Osu.Scoring protected override void Reset(bool storeResults) { base.Reset(storeResults); - - scoreResultCounts.Clear(); comboResultCounts.Clear(); } - public override void PopulateScore(ScoreInfo score) - { - base.PopulateScore(score); - - score.Statistics[HitResult.Great] = scoreResultCounts.GetOrDefault(HitResult.Great); - score.Statistics[HitResult.Good] = scoreResultCounts.GetOrDefault(HitResult.Good); - score.Statistics[HitResult.Meh] = scoreResultCounts.GetOrDefault(HitResult.Meh); - score.Statistics[HitResult.Miss] = scoreResultCounts.GetOrDefault(HitResult.Miss); - } - private const double harshness = 0.01; protected override void ApplyResult(JudgementResult result) @@ -59,10 +45,7 @@ namespace osu.Game.Rulesets.Osu.Scoring var osuResult = (OsuJudgementResult)result; if (result.Type != HitResult.None) - { - scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1; comboResultCounts[osuResult.ComboType] = comboResultCounts.GetOrDefault(osuResult.ComboType) + 1; - } switch (result.Type) { diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index ebcf78435c..b2a1bfaabd 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -2,8 +2,10 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Diagnostics; using osu.Framework.Configuration; +using osu.Framework.Extensions; using osu.Framework.Extensions.TypeExtensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; @@ -155,6 +157,8 @@ namespace osu.Game.Rulesets.Scoring AllJudged?.Invoke(); } + private readonly Dictionary scoreResultCounts = new Dictionary(); + /// /// Retrieve a score populated with data for the current play this processor is responsible for. /// @@ -166,6 +170,13 @@ namespace osu.Game.Rulesets.Scoring score.Accuracy = Math.Round(Accuracy, 4); score.Rank = Rank; score.Date = DateTimeOffset.Now; + + score.Statistics[HitResult.Perfect] = scoreResultCounts.GetOrDefault(HitResult.Perfect); + score.Statistics[HitResult.Great] = scoreResultCounts.GetOrDefault(HitResult.Great); + score.Statistics[HitResult.Good] = scoreResultCounts.GetOrDefault(HitResult.Good); + score.Statistics[HitResult.Ok] = scoreResultCounts.GetOrDefault(HitResult.Ok); + score.Statistics[HitResult.Meh] = scoreResultCounts.GetOrDefault(HitResult.Meh); + score.Statistics[HitResult.Miss] = scoreResultCounts.GetOrDefault(HitResult.Miss); } public abstract double GetStandardisedScore(); @@ -275,6 +286,8 @@ namespace osu.Game.Rulesets.Scoring updateScore(); } + private readonly Dictionary scoreResultCounts = new Dictionary(); + /// /// Applies the score change of a to this . /// @@ -286,6 +299,9 @@ namespace osu.Game.Rulesets.Scoring JudgedHits++; + if (result.Type != HitResult.None) + scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1; + if (result.Judgement.AffectsCombo) { switch (result.Type) @@ -362,6 +378,8 @@ namespace osu.Game.Rulesets.Scoring protected override void Reset(bool storeResults) { + scoreResultCounts.Clear(); + if (storeResults) { MaxHits = JudgedHits; From 5977fc838ffc58037e9afa1865cd3963319c420e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 21:59:08 +0900 Subject: [PATCH 202/220] Limit available durations for the time being --- .../Screens/Multi/Match/Components/MatchSettingsOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 72136b1874..68c97d16eb 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -163,10 +163,10 @@ namespace osu.Game.Screens.Multi.Match.Components TimeSpan.FromHours(4), TimeSpan.FromHours(8), TimeSpan.FromHours(12), - TimeSpan.FromHours(16), + //TimeSpan.FromHours(16), TimeSpan.FromHours(24), - TimeSpan.FromDays(3), - TimeSpan.FromDays(7) + //TimeSpan.FromDays(3), + //TimeSpan.FromDays(7) } } }, From 101fdf993ef1bf4de4111c8f9936cc47b9603646 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 21:59:43 +0900 Subject: [PATCH 203/220] Ensure mods are set prior to starting play --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 9ff1b84b41..55a5a2c85e 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -12,7 +11,6 @@ using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Play; using osu.Game.Screens.Play; @@ -136,7 +134,6 @@ namespace osu.Game.Screens.Multi.Match base.LoadComplete(); bindings.CurrentBeatmap.BindValueChanged(setBeatmap, true); - bindings.CurrentMods.BindValueChanged(setMods, true); bindings.CurrentRuleset.BindValueChanged(setRuleset, true); } @@ -148,11 +145,6 @@ namespace osu.Game.Screens.Multi.Match game?.ForcefullySetBeatmap(beatmapManager.GetWorkingBeatmap(localBeatmap)); } - private void setMods(IEnumerable mods) - { - Beatmap.Value.Mods.Value = mods.ToArray(); - } - private void setRuleset(RulesetInfo ruleset) { if (ruleset == null) @@ -184,6 +176,8 @@ namespace osu.Game.Screens.Multi.Match private void onStart() { + Beatmap.Value.Mods.Value = bindings.CurrentMods.Value.ToArray(); + switch (bindings.Type.Value) { default: From cf079690e528cadd4387402ca2a050d388604796 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 22:13:51 +0900 Subject: [PATCH 204/220] Use LargeTextureStore for online retrievals --- osu.Game/Beatmaps/Drawables/BeatmapSetCover.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetCover.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetCover.cs index 883c05f1e4..e09da2fb72 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetCover.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetCover.cs @@ -23,7 +23,7 @@ namespace osu.Game.Beatmaps.Drawables } [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load(LargeTextureStore textures) { string resource = null; From a62405d82d7711a642cef677596b5ba563c07c12 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 22:16:58 +0900 Subject: [PATCH 205/220] Fix plays with mods not submitting --- osu.Game/Screens/Play/Player.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f2390318b0..c102fb0223 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -301,7 +301,8 @@ namespace osu.Game.Screens.Play { Beatmap = Beatmap.Value.BeatmapInfo, Ruleset = ruleset, - User = api.LocalUser.Value + Mods = Beatmap.Value.Mods.Value.ToArray(), + User = api.LocalUser.Value, }; ScoreProcessor.PopulateScore(score); From 99ed0098386d73ffd8c7431672568cdf0e899b67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Dec 2018 22:31:40 +0900 Subject: [PATCH 206/220] Fix extra hit result types showing on ranking screen --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index b2a1bfaabd..e86c218797 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using osu.Framework.Configuration; using osu.Framework.Extensions; using osu.Framework.Extensions.TypeExtensions; @@ -59,6 +60,11 @@ namespace osu.Game.Rulesets.Scoring /// public readonly BindableInt Combo = new BindableInt(); + /// + /// Create a for this processor. + /// + protected virtual HitWindows CreateHitWindows() => new HitWindows(); + /// /// The current rank. /// @@ -171,12 +177,10 @@ namespace osu.Game.Rulesets.Scoring score.Rank = Rank; score.Date = DateTimeOffset.Now; - score.Statistics[HitResult.Perfect] = scoreResultCounts.GetOrDefault(HitResult.Perfect); - score.Statistics[HitResult.Great] = scoreResultCounts.GetOrDefault(HitResult.Great); - score.Statistics[HitResult.Good] = scoreResultCounts.GetOrDefault(HitResult.Good); - score.Statistics[HitResult.Ok] = scoreResultCounts.GetOrDefault(HitResult.Ok); - score.Statistics[HitResult.Meh] = scoreResultCounts.GetOrDefault(HitResult.Meh); - score.Statistics[HitResult.Miss] = scoreResultCounts.GetOrDefault(HitResult.Miss); + var hitWindows = CreateHitWindows(); + + foreach (var result in Enum.GetValues(typeof(HitResult)).OfType().Where(r => hitWindows.IsHitResultAllowed(r))) + score.Statistics[result] = scoreResultCounts.GetOrDefault(result); } public abstract double GetStandardisedScore(); From b64932f6db381220cc7659bdc0caf2722a585936 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 22:36:57 +0900 Subject: [PATCH 207/220] Implement hit windows --- .../Objects/CatchHitWindows.cs | 23 +++++++++++++++++++ .../Scoring/CatchScoreProcessor.cs | 3 +++ .../Scoring/ManiaScoreProcessor.cs | 3 +++ .../Scoring/TaikoScoreProcessor.cs | 3 +++ 4 files changed, 32 insertions(+) create mode 100644 osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs new file mode 100644 index 0000000000..1cf2694a90 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Catch.Objects +{ + public class CatchHitWindows : HitWindows + { + public override bool IsHitResultAllowed(HitResult result) + { + switch (result) + { + case HitResult.Perfect: + case HitResult.Miss: + return true; + } + + return false; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 778d972b52..57f4355d6a 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -5,6 +5,7 @@ using System; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -41,5 +42,7 @@ namespace osu.Game.Rulesets.Catch.Scoring Health.Value += Math.Max(result.Judgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness; } + + protected override HitWindows CreateHitWindows() => new CatchHitWindows(); } } diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 12b32c46ee..20a665c314 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -5,6 +5,7 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -157,5 +158,7 @@ namespace osu.Game.Rulesets.Mania.Scoring } } } + + protected override HitWindows CreateHitWindows() => new ManiaHitWindows(); } } diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 318efdbf3e..87481c800d 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -3,6 +3,7 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.UI; @@ -65,5 +66,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring Health.Value = 0; } + + protected override HitWindows CreateHitWindows() => new TaikoHitWindows(); } } From 338b95dd6304732b4458bd54fa5fe396bee6f2e7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 22:48:24 +0900 Subject: [PATCH 208/220] Fix none result getting included --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index e86c218797..ae0f0dda50 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -179,7 +179,7 @@ namespace osu.Game.Rulesets.Scoring var hitWindows = CreateHitWindows(); - foreach (var result in Enum.GetValues(typeof(HitResult)).OfType().Where(r => hitWindows.IsHitResultAllowed(r))) + foreach (var result in Enum.GetValues(typeof(HitResult)).OfType().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r))) score.Statistics[result] = scoreResultCounts.GetOrDefault(result); } From 5c1280c0921e1a3e952ae71e9233b8f7b2902081 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 28 Dec 2018 00:14:00 +0900 Subject: [PATCH 209/220] Fix missing hitwindows --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 7cd78c8be7..a24efe4a1e 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using osu.Framework.Extensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; @@ -72,5 +73,7 @@ namespace osu.Game.Rulesets.Osu.Scoring } protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement); + + protected override HitWindows CreateHitWindows() => new OsuHitWindows(); } } From be86281c729945106e07a9330ab2e9bc102a63e2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 28 Dec 2018 00:24:02 +0900 Subject: [PATCH 210/220] Fix score results not populated --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index ae0f0dda50..4b3012192d 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -163,8 +163,6 @@ namespace osu.Game.Rulesets.Scoring AllJudged?.Invoke(); } - private readonly Dictionary scoreResultCounts = new Dictionary(); - /// /// Retrieve a score populated with data for the current play this processor is responsible for. /// @@ -180,9 +178,11 @@ namespace osu.Game.Rulesets.Scoring var hitWindows = CreateHitWindows(); foreach (var result in Enum.GetValues(typeof(HitResult)).OfType().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r))) - score.Statistics[result] = scoreResultCounts.GetOrDefault(result); + score.Statistics[result] = GetStatistic(result); } + protected abstract int GetStatistic(HitResult result); + public abstract double GetStandardisedScore(); } @@ -378,6 +378,8 @@ namespace osu.Game.Rulesets.Scoring } } + protected override int GetStatistic(HitResult result) => scoreResultCounts.GetOrDefault(result); + public override double GetStandardisedScore() => getScore(ScoringMode.Standardised); protected override void Reset(bool storeResults) From f2f1ba8cbe0c82254a37d19316b94ff9b501caf6 Mon Sep 17 00:00:00 2001 From: Lanyun Hou Date: Fri, 28 Dec 2018 00:43:20 +0800 Subject: [PATCH 211/220] Fix typo in line 42 --- osu.Game/Online/PollingComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/PollingComponent.cs b/osu.Game/Online/PollingComponent.cs index 36a42b5d0a..6296608e5d 100644 --- a/osu.Game/Online/PollingComponent.cs +++ b/osu.Game/Online/PollingComponent.cs @@ -39,7 +39,7 @@ namespace osu.Game.Online /// /// /// - /// The initial time in milliseconds to wait between polls. Setting to zero stops al polling. + /// The initial time in milliseconds to wait between polls. Setting to zero stops all polling. protected PollingComponent(double timeBetweenPolls = 0) { TimeBetweenPolls = timeBetweenPolls; From a7db0bbb91695dc7d84a2aca63feedc8ecf05f62 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 28 Dec 2018 01:45:19 +0900 Subject: [PATCH 212/220] Sort rooms based on their API position --- .../Visual/TestCaseLoungeRoomsContainer.cs | 2 ++ .../Visual/TestCaseMatchSettingsOverlay.cs | 2 ++ osu.Game/Online/Multiplayer/Room.cs | 8 ++++++++ osu.Game/Screens/Multi/IRoomManager.cs | 5 +++++ .../Multi/Lounge/Components/RoomsContainer.cs | 16 ++++++++++++++++ osu.Game/Screens/Multi/RoomManager.cs | 13 +++++++++++-- 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs index e9dfb0f041..3e9f2fb3a4 100644 --- a/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs @@ -71,6 +71,8 @@ namespace osu.Game.Tests.Visual private class TestRoomManager : IRoomManager { + public event Action RoomsUpdated; + public readonly BindableCollection Rooms = new BindableCollection(); IBindableCollection IRoomManager.Rooms => Rooms; diff --git a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs index afce8999b4..7fb9d4dded 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs @@ -136,6 +136,8 @@ namespace osu.Game.Tests.Visual public Func CreateRequested; + public event Action RoomsUpdated; + public IBindableCollection Rooms { get; } = null; public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 0d6a8ae3a8..448f5ced91 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -79,6 +79,12 @@ namespace osu.Game.Online.Multiplayer set => MaxAttempts.Value = value; } + /// + /// The position of this in the list. This is not read from or written to the API. + /// + [JsonIgnore] + public int Position = -1; + public void CopyFrom(Room other) { RoomID.Value = other.RoomID; @@ -103,6 +109,8 @@ namespace osu.Game.Online.Multiplayer Playlist.AddRange(other.Playlist); else if (other.Playlist.Count > 0) Playlist.First().ID = other.Playlist.First().ID; + + Position = other.Position; } public bool ShouldSerializeRoomID() => false; diff --git a/osu.Game/Screens/Multi/IRoomManager.cs b/osu.Game/Screens/Multi/IRoomManager.cs index a929e1a0f7..f0dbcb0e71 100644 --- a/osu.Game/Screens/Multi/IRoomManager.cs +++ b/osu.Game/Screens/Multi/IRoomManager.cs @@ -10,6 +10,11 @@ namespace osu.Game.Screens.Multi { public interface IRoomManager { + /// + /// Invoked when the s have been updated. + /// + event Action RoomsUpdated; + /// /// All the active s. /// diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 33b71d1203..5133e96a52 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -52,6 +52,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components rooms.ItemsAdded += addRooms; rooms.ItemsRemoved += removeRooms; + roomManager.RoomsUpdated += updateSorting; + addRooms(rooms); } @@ -104,6 +106,12 @@ namespace osu.Game.Screens.Multi.Lounge.Components } } + private void updateSorting() + { + foreach (var room in roomFlow) + roomFlow.SetLayoutPosition(room, room.Room.Position); + } + private void selectRoom(Room room) { var drawable = roomFlow.FirstOrDefault(r => r.Room == room); @@ -115,5 +123,13 @@ namespace osu.Game.Screens.Multi.Lounge.Components selectedRoom.Value = room; } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (roomManager != null) + roomManager.RoomsUpdated -= updateSorting; + } } } diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 6fe2307d8b..96dbe79258 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -19,6 +19,8 @@ namespace osu.Game.Screens.Multi { public class RoomManager : PollingComponent, IRoomManager { + public event Action RoomsUpdated; + private readonly BindableCollection rooms = new BindableCollection(); public IBindableCollection Rooms => rooms; @@ -44,6 +46,7 @@ namespace osu.Game.Screens.Multi public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) { room.Host.Value = api.LocalUser; + room.RoomID.Value = 100; var req = new CreateRoomRequest(room); @@ -52,6 +55,8 @@ namespace osu.Game.Screens.Multi update(room, result); addRoom(room); + RoomsUpdated?.Invoke(); + onSuccess?.Invoke(room); }; @@ -125,13 +130,17 @@ namespace osu.Game.Screens.Multi rooms.Remove(r); } - // Add new matches, or update existing - foreach (var r in result) + for (int i = 0; i < result.Count; i++) { + var r = result[i]; + r.Position = i; + update(r, r); addRoom(r); } + RoomsUpdated?.Invoke(); + tcs.SetResult(true); }; From 72482aff8d61cabd0427ed631f8e1d473a18ff86 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 28 Dec 2018 01:48:13 +0900 Subject: [PATCH 213/220] Whoops --- osu.Game/Screens/Multi/RoomManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 96dbe79258..fab19c3fd7 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -46,7 +46,6 @@ namespace osu.Game.Screens.Multi public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) { room.Host.Value = api.LocalUser; - room.RoomID.Value = 100; var req = new CreateRoomRequest(room); From 55607634b4cebcd74c1130293222845923099525 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Dec 2018 13:28:07 +0900 Subject: [PATCH 214/220] Fix covers being loaded even when off-screen --- .../UpdateableBeatmapBackgroundSprite.cs | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index 93783f757b..724c6d656a 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -25,23 +25,26 @@ namespace osu.Game.Beatmaps.Drawables protected override Drawable CreateDrawable(BeatmapInfo model) { - Drawable drawable; + return new DelayedLoadUnloadWrapper(() => { + Drawable drawable; - var localBeatmap = beatmaps.GetWorkingBeatmap(model); + var localBeatmap = beatmaps.GetWorkingBeatmap(model); - if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null) - drawable = new BeatmapSetCover(model.BeatmapSet); - else - drawable = new BeatmapBackgroundSprite(localBeatmap); + if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null) + drawable = new BeatmapSetCover(model.BeatmapSet); + else + drawable = new BeatmapBackgroundSprite(localBeatmap); - drawable.RelativeSizeAxes = Axes.Both; - drawable.Anchor = Anchor.Centre; - drawable.Origin = Anchor.Centre; - drawable.FillMode = FillMode.Fill; + drawable.RelativeSizeAxes = Axes.Both; + drawable.Anchor = Anchor.Centre; + drawable.Origin = Anchor.Centre; + drawable.FillMode = FillMode.Fill; + drawable.OnLoadComplete = d => d.FadeInFromZero(400); - return drawable; + return drawable; + }, 500, 10000); } - protected override double FadeDuration => 400; + protected override double FadeDuration => 0; } } From 0047f29ec8208bea117135bd9d28be414dc73813 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Sun, 30 Dec 2018 22:40:17 +0100 Subject: [PATCH 215/220] move missing newline to front of "Plays with..." --- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 23739d8ad1..90f4e5851d 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -396,11 +396,11 @@ namespace osu.Game.Overlays.Profile infoTextLeft.NewLine(); infoTextLeft.AddText("Last seen ", lightText); infoTextLeft.AddText(new DrawableDate(user.LastVisit.Value), boldItalic); - infoTextLeft.NewParagraph(); } if (user.PlayStyle?.Length > 0) { + infoTextLeft.NewParagraph(); infoTextLeft.AddText("Plays with ", lightText); infoTextLeft.AddText(string.Join(", ", user.PlayStyle), boldItalic); } From 2d405bfc43b819c2ad73aed46c8ba68022f89e62 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Jan 2019 16:33:52 +0900 Subject: [PATCH 216/220] Add back options for 3 and 7 day long rooms --- .../Screens/Multi/Match/Components/MatchSettingsOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 68c97d16eb..69ca4b1deb 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -165,8 +165,8 @@ namespace osu.Game.Screens.Multi.Match.Components TimeSpan.FromHours(12), //TimeSpan.FromHours(16), TimeSpan.FromHours(24), - //TimeSpan.FromDays(3), - //TimeSpan.FromDays(7) + TimeSpan.FromDays(3), + TimeSpan.FromDays(7) } } }, From c56d8b75c15d2c0a5f0145d18c3b7d1cf2286223 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 3 Jan 2019 17:43:10 +0900 Subject: [PATCH 217/220] Cache slider's endposition --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 26 ++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index d508ec2636..ffb7f7be9e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -7,6 +7,7 @@ using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; using osu.Game.Rulesets.Objects; using System.Linq; +using osu.Framework.Caching; using osu.Framework.Configuration; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -26,8 +27,11 @@ namespace osu.Game.Rulesets.Osu.Objects public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; public double Duration => EndTime - StartTime; + private Cached endPositionCache; + + public override Vector2 EndPosition => endPositionCache.IsValid ? endPositionCache.Value : endPositionCache.Value = Position + this.CurvePositionAt(1); + public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t); - public override Vector2 EndPosition => Position + this.CurvePositionAt(1); public override int ComboIndex { @@ -56,7 +60,11 @@ namespace osu.Game.Rulesets.Osu.Objects public SliderPath Path { get => PathBindable.Value; - set => PathBindable.Value = value; + set + { + PathBindable.Value = value; + endPositionCache.Invalidate(); + } } public double Distance => Path.Distance; @@ -73,6 +81,8 @@ namespace osu.Game.Rulesets.Osu.Objects if (TailCircle != null) TailCircle.Position = EndPosition; + + endPositionCache.Invalidate(); } } @@ -92,7 +102,17 @@ namespace osu.Game.Rulesets.Osu.Objects public List> NodeSamples { get; set; } = new List>(); - public int RepeatCount { get; set; } + private int repeatCount; + + public int RepeatCount + { + get => repeatCount; + set + { + repeatCount = value; + endPositionCache.Invalidate(); + } + } /// /// The length of one span of this . From 273b14b19cc74a2feb60e0940f60a6f206f1e3e3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 3 Jan 2019 18:51:47 +0900 Subject: [PATCH 218/220] Add a maximum length for slider ticks to be generated --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index ffb7f7be9e..2d82f7aecf 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -24,6 +24,12 @@ namespace osu.Game.Rulesets.Osu.Objects /// private const float base_scoring_distance = 100; + /// + /// A very lenient maximum length of a slider for ticks to be generated. + /// This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage. + /// + private const double max_length_for_ticks = 100000; + public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; public double Duration => EndTime - StartTime; @@ -189,7 +195,7 @@ namespace osu.Game.Rulesets.Osu.Objects private void createTicks() { - var length = Path.Distance; + var length = Math.Min(max_length_for_ticks, Path.Distance); var tickDistance = MathHelper.Clamp(TickDistance, 0, length); if (tickDistance == 0) return; From 3fa5a33fb1edef5d18861c4dbb04928d6cf5252d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 3 Jan 2019 18:58:07 +0900 Subject: [PATCH 219/220] Inline const --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 2d82f7aecf..2af1de7355 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -24,12 +24,6 @@ namespace osu.Game.Rulesets.Osu.Objects /// private const float base_scoring_distance = 100; - /// - /// A very lenient maximum length of a slider for ticks to be generated. - /// This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage. - /// - private const double max_length_for_ticks = 100000; - public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; public double Duration => EndTime - StartTime; @@ -195,7 +189,11 @@ namespace osu.Game.Rulesets.Osu.Objects private void createTicks() { - var length = Math.Min(max_length_for_ticks, Path.Distance); + // A very lenient maximum length of a slider for ticks to be generated. + // This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage. + const double max_length = 100000; + + var length = Math.Min(max_length, Path.Distance); var tickDistance = MathHelper.Clamp(TickDistance, 0, length); if (tickDistance == 0) return; From 7d1163a7d2e3127a9154175578e53eb04bb6cad8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Jan 2019 15:49:23 +0900 Subject: [PATCH 220/220] Remove unnecessary null check --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e02de917eb..14dc644100 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -297,7 +297,7 @@ namespace osu.Game.Screens.Play protected virtual ScoreInfo CreateScore() { - var score = RulesetContainer?.ReplayScore?.ScoreInfo ?? new ScoreInfo + var score = RulesetContainer.ReplayScore?.ScoreInfo ?? new ScoreInfo { Beatmap = Beatmap.Value.BeatmapInfo, Ruleset = ruleset,