mirror of
https://github.com/ppy/osu.git
synced 2025-01-27 02:32:59 +08:00
Fix handling of local echo deduplication
This commit is contained in:
parent
4f8e912f06
commit
58396d49dc
@ -28,6 +28,7 @@ namespace osu.Game.Online.API.Requests
|
||||
req.AddParameter(@"target_id", user.Id.ToString());
|
||||
req.AddParameter(@"message", message.Content);
|
||||
req.AddParameter(@"is_action", message.IsAction.ToString().ToLowerInvariant());
|
||||
req.AddParameter(@"uuid", message.Uuid);
|
||||
return req;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace osu.Game.Online.API.Requests
|
||||
req.Method = HttpMethod.Post;
|
||||
req.AddParameter(@"is_action", Message.IsAction.ToString().ToLowerInvariant());
|
||||
req.AddParameter(@"message", Message.Content);
|
||||
req.AddParameter(@"uuid", Message.Uuid);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
@ -134,6 +134,14 @@ namespace osu.Game.Online.Chat
|
||||
/// <param name="messages"></param>
|
||||
public void AddNewMessages(params Message[] messages)
|
||||
{
|
||||
foreach (var m in messages)
|
||||
{
|
||||
LocalEchoMessage localEcho = pendingMessages.FirstOrDefault(local => local.Uuid == m.Uuid);
|
||||
|
||||
if (localEcho != null)
|
||||
ReplaceMessage(localEcho, m);
|
||||
}
|
||||
|
||||
messages = messages.Except(Messages).ToArray();
|
||||
|
||||
if (messages.Length == 0) return;
|
||||
|
@ -85,8 +85,21 @@ namespace osu.Game.Online.Chat
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
connector.ChannelJoined += ch => Schedule(() => joinChannel(ch));
|
||||
connector.ChannelJoined += ch => Schedule(() =>
|
||||
{
|
||||
var localChannel = getChannel(ch);
|
||||
|
||||
if (localChannel != ch)
|
||||
{
|
||||
localChannel.Joined.Value = true;
|
||||
localChannel.Id = ch.Id;
|
||||
}
|
||||
|
||||
joinChannel(localChannel);
|
||||
});
|
||||
|
||||
connector.NewMessages += msgs => Schedule(() => addMessages(msgs));
|
||||
|
||||
connector.PresenceReceived += () => Schedule(() =>
|
||||
{
|
||||
if (!channelsInitialised)
|
||||
@ -189,7 +202,8 @@ namespace osu.Game.Online.Chat
|
||||
Timestamp = DateTimeOffset.Now,
|
||||
ChannelId = target.Id,
|
||||
IsAction = isAction,
|
||||
Content = text
|
||||
Content = text,
|
||||
Uuid = Guid.NewGuid().ToString()
|
||||
};
|
||||
|
||||
target.AddLocalEcho(message);
|
||||
@ -199,13 +213,7 @@ namespace osu.Game.Online.Chat
|
||||
{
|
||||
var createNewPrivateMessageRequest = new CreateNewPrivateMessageRequest(target.Users.First(), message);
|
||||
|
||||
createNewPrivateMessageRequest.Success += createRes =>
|
||||
{
|
||||
target.Id = createRes.ChannelID;
|
||||
target.ReplaceMessage(message, createRes.Message);
|
||||
dequeueAndRun();
|
||||
};
|
||||
|
||||
createNewPrivateMessageRequest.Success += _ => dequeueAndRun();
|
||||
createNewPrivateMessageRequest.Failure += exception =>
|
||||
{
|
||||
handlePostException(exception);
|
||||
@ -219,12 +227,7 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
var req = new PostMessageRequest(message);
|
||||
|
||||
req.Success += m =>
|
||||
{
|
||||
target.ReplaceMessage(message, m);
|
||||
dequeueAndRun();
|
||||
};
|
||||
|
||||
req.Success += m => dequeueAndRun();
|
||||
req.Failure += exception =>
|
||||
{
|
||||
handlePostException(exception);
|
||||
@ -403,7 +406,20 @@ namespace osu.Game.Online.Chat
|
||||
{
|
||||
Channel found = null;
|
||||
|
||||
bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : lookup.Name == ch.Name;
|
||||
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;
|
||||
}
|
||||
|
||||
var available = AvailableChannels.FirstOrDefault(lookupCondition);
|
||||
if (available != null)
|
||||
|
@ -37,6 +37,12 @@ namespace osu.Game.Online.Chat
|
||||
set => Sender = new APIUser { Id = value };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A unique identifier for this message. Sent to and from osu!web to use for deduplication.
|
||||
/// </summary>
|
||||
[JsonProperty(@"uuid")]
|
||||
public string Uuid { get; set; } = string.Empty;
|
||||
|
||||
[JsonConstructor]
|
||||
public Message()
|
||||
{
|
||||
|
@ -2,9 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@ -126,12 +124,10 @@ namespace osu.Game.Online.Notifications.WebSocket
|
||||
NewChatMessageData? messageData = JsonConvert.DeserializeObject<NewChatMessageData>(message.Data.ToString());
|
||||
Debug.Assert(messageData != null);
|
||||
|
||||
List<Message> messages = messageData.Messages.Where(m => m.Sender.OnlineID != api.LocalUser.Value.OnlineID).ToList();
|
||||
foreach (var msg in messageData.Messages)
|
||||
HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId, Messages = { msg } });
|
||||
|
||||
foreach (var msg in messages)
|
||||
HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId });
|
||||
|
||||
HandleMessages(messages);
|
||||
HandleMessages(messageData.Messages);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user