Better handling for joining channels with only ID

This commit is contained in:
Dan Balasescu 2022-11-07 11:52:07 +09:00
parent e3adf5a985
commit cf03001c83
5 changed files with 51 additions and 28 deletions

View File

@ -0,0 +1,19 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests
{
public class GetChannelRequest : APIRequest<GetChannelResponse>
{
private readonly long channelId;
public GetChannelRequest(long channelId)
{
this.channelId = channelId;
}
protected override string Target => $"chat/channels/{channelId}";
}
}

View File

@ -0,0 +1,19 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Online.Chat;
namespace osu.Game.Online.API.Requests.Responses
{
[JsonObject(MemberSerialization.OptIn)]
public class GetChannelResponse
{
[JsonProperty(@"channel")]
public Channel Channel { get; set; } = null!;
[JsonProperty(@"users")]
public List<APIUser> Users { get; set; } = null!;
}
}

View File

@ -88,15 +88,14 @@ namespace osu.Game.Online.Chat
{
connector.ChannelJoined += ch => Schedule(() =>
{
var localChannel = getChannel(ch);
if (localChannel != ch)
if (ch.Joined.Value)
JoinChannel(ch);
else
{
localChannel.Joined.Value = true;
localChannel.Id = ch.Id;
var req = new GetChannelRequest(ch.Id);
req.Success += response => JoinChannel(response.Channel);
api.Queue(req);
}
joinChannel(localChannel);
});
connector.ChannelParted += ch => Schedule(() => LeaveChannel(getChannel(ch)));
@ -421,20 +420,7 @@ namespace osu.Game.Online.Chat
{
Channel found = null;
bool lookupCondition(Channel ch)
{
// If both channels have an id, use that.
if (lookup.Id > 0 && ch.Id > 0)
return ch.Id == lookup.Id;
// In the case that the local echo is received in a new channel (i.e. one that does not yet have an ID),
// then we need to check for any existing channel with the message containing the same message matched by UUID.
if (lookup.Messages.Count > 0 && ch.Messages.Any(m => m.Uuid == lookup.Messages.Last().Uuid))
return true;
// As a last resort, fallback to matching by name.
return lookup.Name == ch.Name;
}
bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : ch.Name == lookup.Name;
var available = AvailableChannels.FirstOrDefault(lookupCondition);
if (available != null)

View File

@ -46,7 +46,10 @@ namespace osu.Game.Online.Notifications
if (updates?.Presence != null)
{
foreach (var channel in updates.Presence)
{
channel.Joined.Value = true;
HandleJoinedChannel(channel);
}
//todo: handle left channels
@ -59,12 +62,7 @@ namespace osu.Game.Online.Notifications
return fetchReq;
}
protected void HandleJoinedChannel(Channel channel)
{
// we received this from the server so should mark the channel already joined.
channel.Joined.Value = true;
ChannelJoined?.Invoke(channel);
}
protected void HandleJoinedChannel(Channel channel) => ChannelJoined?.Invoke(channel);
protected void HandleChannelParted(Channel channel) => ChannelParted?.Invoke(channel);

View File

@ -119,6 +119,7 @@ namespace osu.Game.Online.Notifications.WebSocket
Channel? joinedChannel = JsonConvert.DeserializeObject<Channel>(message.Data.ToString());
Debug.Assert(joinedChannel != null);
joinedChannel.Joined.Value = true;
HandleJoinedChannel(joinedChannel);
break;
@ -138,7 +139,7 @@ namespace osu.Game.Online.Notifications.WebSocket
Debug.Assert(messageData != null);
foreach (var msg in messageData.Messages)
HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId, Messages = { msg } });
HandleJoinedChannel(new Channel { Id = msg.ChannelId });
HandleMessages(messageData.Messages);
break;