From eab2776755694526f8f99c6dc1aec4718216d4b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Wed, 21 Nov 2018 17:14:08 +0900 Subject: [PATCH 1/8] Fix a crash on leaving the selected channel --- osu.Game/Overlays/ChatOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index e45373c36f..6a5b72c0f3 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -209,7 +209,6 @@ namespace osu.Game.Overlays { textbox.Current.Disabled = true; currentChannelContainer.Clear(false); - channelTabControl.Current.Value = null; return; } From 4cde66240dcba75444ac1693aef3a117498cb122 Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Wed, 21 Nov 2018 17:14:48 +0900 Subject: [PATCH 2/8] Fix default channels not being joined --- osu.Game/Online/Chat/ChannelManager.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 9014fce18d..9ee6cfa483 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. +// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; @@ -362,12 +362,6 @@ namespace osu.Game.Online.Chat } } - if (!channelsInitialised) - { - channelsInitialised = true; - // we want this to run after the first presence so we can see if the user is in any channels already. - initializeChannels(); - } //todo: handle left channels @@ -379,6 +373,13 @@ namespace osu.Game.Online.Chat lastMessageId = updates.Messages.LastOrDefault()?.Id ?? lastMessageId; } + if (!channelsInitialised) + { + channelsInitialised = true; + // we want this to run after the first presence so we can see if the user is in any channels already. + initializeChannels(); + } + fetchUpdates(); }; From 88f82eb722738f323314afa5e51467deecd9b01a Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Wed, 21 Nov 2018 17:15:10 +0900 Subject: [PATCH 3/8] Fix instabilities in channel join logic --- osu.Game/Online/Chat/ChannelManager.cs | 89 +++++++++++++++++--------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 9ee6cfa483..621cdb5737 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. +// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; @@ -223,13 +223,11 @@ namespace osu.Game.Online.Chat { foreach (var channel in channels) { - // add as available if not already - if (AvailableChannels.All(c => c.Id != channel.Id)) - AvailableChannels.Add(channel); + var ch = getChannel(channel, addToAvailable: true); // join any channels classified as "defaults" if (joinDefaults && defaultChannels.Any(c => c.Equals(channel.Name, StringComparison.OrdinalIgnoreCase))) - JoinChannel(channel); + JoinChannel(ch); } }; req.Failure += error => @@ -262,38 +260,68 @@ namespace osu.Game.Online.Chat api.Queue(fetchInitialMsgReq); } - public void JoinChannel(Channel channel) + /// <summary> + /// Find an existing channel instance for the provided channel. Lookup is performed basd on ID. + /// The provided channel may be used if an existing instance is not found. + /// </summary> + /// <param name="lookup">A candidate channel to be used for lookup or permanently on lookup failure.</param> + /// <param name="addToAvailable">Whether the channel should be added to <see cref="AvailableChannels"/> if not already.</param> + /// <param name="addToJoined">Whether the channel should be added to <see cref="JoinedChannels"/> if not already.</param> + /// <returns>The found channel.</returns> + private Channel getChannel(Channel lookup, bool addToAvailable = false, bool addToJoined = false) { - if (channel == null) return; + Channel found = null; - // ReSharper disable once AccessToModifiedClosure - var existing = JoinedChannels.FirstOrDefault(c => c.Id == channel.Id); + var available = AvailableChannels.FirstOrDefault(c => c.Id == lookup.Id); + if (available != null) + found = available; - if (existing != null) + var joined = JoinedChannels.FirstOrDefault(c => c.Id == lookup.Id); + if (found == null && joined != null) + found = joined; + + if (found == null) { - // if we already have this channel loaded, we don't want to make a second one. - channel = existing; - } - else - { - var foundSelf = channel.Users.FirstOrDefault(u => u.Id == api.LocalUser.Value.Id); + found = lookup; + + // if we're using a channel object from the server, we want to remove ourselves from the users list. + // this is because we check the first user in the channel to display a name/icon on tabs for now. + var foundSelf = found.Users.FirstOrDefault(u => u.Id == api.LocalUser.Value.Id); if (foundSelf != null) - channel.Users.Remove(foundSelf); + found.Users.Remove(foundSelf); + } - JoinedChannels.Add(channel); + if (joined == null && addToJoined) JoinedChannels.Add(found); + if (available == null && addToAvailable) AvailableChannels.Add(found); - if (channel.Type == ChannelType.Public && !channel.Joined) + return found; + } + + /// <summary> + /// Joins a channel if it has not already been joined. + /// </summary> + /// <param name="channel">The channel to join.</param> + /// <param name="alreadyJoined">Whether the channel has already been joined server-side. Will skip a join request.</param> + /// <returns>The joined channel. Note that this may not match the parameter channel as it is a backed object.</returns> + public Channel JoinChannel(Channel channel, bool alreadyJoined = false) + { + if (channel == null) return null; + + channel = getChannel(channel, addToJoined: true); + + // ensure we are joined to the channel + if (!channel.Joined.Value) + { + if (!alreadyJoined && channel.Type == ChannelType.Public) { var req = new JoinChannelRequest(channel, api.LocalUser); - req.Success += () => - { - channel.Joined.Value = true; - JoinChannel(channel); - }; + req.Success += () => JoinChannel(channel, true); req.Failure += ex => LeaveChannel(channel); api.Queue(req); - return; + return channel; } + + channel.Joined.Value = true; } if (CurrentChannel.Value == null) @@ -304,6 +332,8 @@ namespace osu.Game.Online.Chat // let's fetch a small number of messages to bring us up-to-date with the backlog. fetchInitalMessages(channel); } + + return channel; } public void LeaveChannel(Channel channel) @@ -353,13 +383,8 @@ namespace osu.Game.Online.Chat { foreach (var channel in updates.Presence) { - if (!channel.Joined.Value) - { - // we received this from the server so should mark the channel already joined. - channel.Joined.Value = true; - - JoinChannel(channel); - } + // we received this from the server so should mark the channel already joined. + JoinChannel(channel, true); } From d67792168029a6d9f2ea491d102d45aa3ce46c0d Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Wed, 21 Nov 2018 18:53:50 +0900 Subject: [PATCH 4/8] Remove excess newline --- osu.Game/Online/Chat/ChannelManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 621cdb5737..3ce162ee30 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -387,7 +387,6 @@ namespace osu.Game.Online.Chat JoinChannel(channel, true); } - //todo: handle left channels handleChannelMessages(updates.Messages); From b31efb7bb992256134d581b30a6b603ffbbe77fc Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Wed, 21 Nov 2018 20:31:47 +0900 Subject: [PATCH 5/8] Fix PM channel type --- osu.Game/Online/Chat/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 3ce162ee30..d9098956ec 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -77,7 +77,7 @@ namespace osu.Game.Online.Chat throw new ArgumentNullException(nameof(user)); CurrentChannel.Value = JoinedChannels.FirstOrDefault(c => c.Type == ChannelType.PM && c.Users.Count == 1 && c.Users.Any(u => u.Id == user.Id)) - ?? new Channel { Name = user.Username, Users = { user } }; + ?? new Channel { Name = user.Username, Users = { user }, Type = ChannelType.PM }; } private void currentChannelChanged(Channel channel) => JoinChannel(channel); From 2126cf0d9a6f68acf52002a018396fba9cf3ec75 Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Wed, 21 Nov 2018 20:44:41 +0900 Subject: [PATCH 6/8] Fix join process for PMs being incorrect --- osu.Game/Online/Chat/ChannelManager.cs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index d9098956ec..a9610e72b1 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -312,16 +312,20 @@ namespace osu.Game.Online.Chat // ensure we are joined to the channel if (!channel.Joined.Value) { - if (!alreadyJoined && channel.Type == ChannelType.Public) + if (alreadyJoined) + channel.Joined.Value = true; + else { - var req = new JoinChannelRequest(channel, api.LocalUser); - req.Success += () => JoinChannel(channel, true); - req.Failure += ex => LeaveChannel(channel); - api.Queue(req); - return channel; + switch (channel.Type) + { + case ChannelType.Public: + var req = new JoinChannelRequest(channel, api.LocalUser); + req.Success += () => JoinChannel(channel, true); + req.Failure += ex => LeaveChannel(channel); + api.Queue(req); + return channel; + } } - - channel.Joined.Value = true; } if (CurrentChannel.Value == null) From a144e975687d43bde1d36fe330f614758793104d Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Thu, 22 Nov 2018 18:27:22 +0900 Subject: [PATCH 7/8] Fix crash on creating two new PM channels --- osu.Game/Online/Chat/ChannelManager.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index a9610e72b1..73ac7c9df4 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -272,11 +272,13 @@ namespace osu.Game.Online.Chat { Channel found = null; - var available = AvailableChannels.FirstOrDefault(c => c.Id == lookup.Id); + bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : lookup.Name == ch.Name; + + var available = AvailableChannels.FirstOrDefault(lookupCondition); if (available != null) found = available; - var joined = JoinedChannels.FirstOrDefault(c => c.Id == lookup.Id); + var joined = JoinedChannels.FirstOrDefault(lookupCondition); if (found == null && joined != null) found = joined; From 6cd69b794d170c8a4c51e8be091166824e1ef5c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Thu, 22 Nov 2018 19:08:46 +0900 Subject: [PATCH 8/8] Fix leaderboard accessing drawables in a possibly invalid state --- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 4a677001a0..0748f68dca 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -310,9 +310,9 @@ namespace osu.Game.Screens.Select.Leaderboards currentPlaceholder = placeholder; } - protected override void Update() + protected override void UpdateAfterChildren() { - base.Update(); + base.UpdateAfterChildren(); var fadeStart = scrollContainer.Current + scrollContainer.DrawHeight;