1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 06:07:25 +08:00

Merge branch 'update-chat-api' into update-framework

This commit is contained in:
Dean Herbert 2018-09-26 19:50:23 +09:00
commit 1b77d9fd05
12 changed files with 179 additions and 50 deletions

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Diagnostics;
using System.Net.Http;
using osu.Framework.Configuration;
using osu.Framework.IO.Network;
@ -40,7 +41,7 @@ namespace osu.Game.Online.API
using (var req = new AccessTokenRequestPassword(username, password)
{
Url = $@"{endpoint}/oauth/token",
Method = HttpMethod.POST,
Method = HttpMethod.Post,
ClientId = clientId,
ClientSecret = clientSecret
})
@ -66,7 +67,7 @@ namespace osu.Game.Online.API
using (var req = new AccessTokenRequestRefresh(refresh)
{
Url = $@"{endpoint}/oauth/token",
Method = HttpMethod.POST,
Method = HttpMethod.Post,
ClientId = clientId,
ClientSecret = clientSecret
})

View File

@ -2,34 +2,19 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using osu.Framework.IO.Network;
using osu.Game.Online.Chat;
namespace osu.Game.Online.API.Requests
{
public class GetMessagesRequest : APIRequest<List<Message>>
{
private readonly List<Channel> channels;
private readonly long? since;
private readonly Channel channel;
public GetMessagesRequest(List<Channel> channels, long? sinceId)
public GetMessagesRequest(Channel channel)
{
this.channels = channels;
since = sinceId;
this.channel = channel;
}
protected override WebRequest CreateWebRequest()
{
string channelString = string.Join(",", channels.Select(x => x.Id));
var req = base.CreateWebRequest();
req.AddParameter(@"channels", channelString);
if (since.HasValue) req.AddParameter(@"since", since.Value.ToString());
return req;
}
protected override string Target => @"chat/messages";
protected override string Target => $@"chat/channels/{channel.Id}/messages";
}
}

View File

@ -0,0 +1,32 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using JetBrains.Annotations;
using osu.Framework.IO.Network;
using osu.Game.Online.Chat;
namespace osu.Game.Online.API.Requests
{
public class GetUpdatesRequest : APIRequest<GetUpdatesResponse>
{
private readonly long since;
private readonly Channel channel;
public GetUpdatesRequest(long sinceId, [CanBeNull] Channel channel = null)
{
this.channel = channel;
since = sinceId;
}
protected override WebRequest CreateWebRequest()
{
var req = base.CreateWebRequest();
if (channel != null) req.AddParameter(@"channel", channel.Id.ToString());
req.AddParameter(@"since", since.ToString());
return req;
}
protected override string Target => @"chat/updates";
}
}

View File

@ -0,0 +1,14 @@
// 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.Collections.Generic;
using osu.Game.Online.Chat;
namespace osu.Game.Online.API.Requests
{
public class GetUpdatesResponse
{
public List<Channel> Presence;
public List<Message> Messages;
}
}

View File

@ -0,0 +1,31 @@
// 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.Net.Http;
using osu.Framework.IO.Network;
using osu.Game.Online.Chat;
using osu.Game.Users;
namespace osu.Game.Online.API.Requests
{
public class JoinChannelRequest : APIRequest
{
private readonly Channel channel;
private readonly User user;
public JoinChannelRequest(Channel channel, User user)
{
this.channel = channel;
this.user = user;
}
protected override WebRequest CreateWebRequest()
{
var req = base.CreateWebRequest();
req.Method = HttpMethod.Put;
return req;
}
protected override string Target => $@"chat/channels/{channel.Id}/users/{user.Id}";
}
}

View File

@ -0,0 +1,31 @@
// 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.Net.Http;
using osu.Framework.IO.Network;
using osu.Game.Online.Chat;
using osu.Game.Users;
namespace osu.Game.Online.API.Requests
{
public class LeaveChannelRequest : APIRequest
{
private readonly Channel channel;
private readonly User user;
public LeaveChannelRequest(Channel channel, User user)
{
this.channel = channel;
this.user = user;
}
protected override WebRequest CreateWebRequest()
{
var req = base.CreateWebRequest();
req.Method = HttpMethod.Delete;
return req;
}
protected override string Target => $@"chat/channels/{channel.Id}/users/{user.Id}";
}
}

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Extensions;
using System.Net.Http;
using osu.Framework.IO.Network;
using osu.Game.Online.Chat;
@ -20,15 +20,13 @@ namespace osu.Game.Online.API.Requests
{
var req = base.CreateWebRequest();
req.Method = HttpMethod.POST;
req.AddParameter(@"target_type", message.TargetType.GetDescription());
req.AddParameter(@"target_id", message.TargetId.ToString());
req.Method = HttpMethod.Post;
req.AddParameter(@"is_action", message.IsAction.ToString().ToLowerInvariant());
req.AddParameter(@"message", message.Content);
return req;
}
protected override string Target => @"chat/messages";
protected override string Target => $@"chat/channels/{message.TargetId}/messages";
}
}

View File

@ -19,11 +19,14 @@ namespace osu.Game.Online.Chat
public string Topic;
[JsonProperty(@"type")]
public string Type;
public ChannelType Type;
[JsonProperty(@"channel_id")]
public int Id;
[JsonProperty(@"last_message_id")]
public long? LastMessageId;
public readonly SortedList<Message> Messages = new SortedList<Message>(Comparer<Message>.Default);
private readonly List<LocalEchoMessage> pendingMessages = new List<LocalEchoMessage>();
@ -51,11 +54,18 @@ namespace osu.Game.Online.Chat
NewMessagesArrived?.Invoke(new[] { message });
}
public bool MessagesLoaded { get; private set; }
public void AddNewMessages(params Message[] messages)
{
messages = messages.Except(Messages).ToArray();
Messages.AddRange(messages);
MessagesLoaded = true;
var maxMessageId = messages.Max(m => m.Id);
if (maxMessageId > LastMessageId)
LastMessageId = maxMessageId;
purgeOldMessages();

View File

@ -0,0 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Online.Chat
{
public enum ChannelType
{
PM,
Public
}
}

View File

@ -47,7 +47,7 @@ namespace osu.Game.Overlays
public const float TAB_AREA_HEIGHT = 50;
private GetMessagesRequest fetchReq;
private GetUpdatesRequest fetchReq;
private readonly ChatTabControl channelTabs;
@ -285,7 +285,7 @@ namespace osu.Game.Overlays
chatBackground.Colour = colours.ChatBlue;
}
private long? lastMessageId;
private long lastMessageId;
private readonly List<Channel> careChannels = new List<Channel>();
@ -304,9 +304,9 @@ namespace osu.Game.Overlays
Scheduler.Add(delegate
{
addChannel(channels.Find(c => c.Name == @"#lazer"));
addChannel(channels.Find(c => c.Name == @"#osu"));
addChannel(channels.Find(c => c.Name == @"#lobby"));
//addChannel(channels.Find(c => c.Name == @"#lazer"));
//addChannel(channels.Find(c => c.Name == @"#osu"));
//addChannel(channels.Find(c => c.Name == @"#lobby"));
channelSelection.OnRequestJoin = addChannel;
channelSelection.OnRequestLeave = removeChannel;
@ -320,7 +320,7 @@ namespace osu.Game.Overlays
};
});
messageRequest = Scheduler.AddDelayed(fetchNewMessages, 1000, true);
messageRequest = Scheduler.AddDelayed(fetchUpdates, 1000, true);
};
api.Queue(req);
@ -362,7 +362,7 @@ namespace osu.Game.Overlays
loadedChannels.Add(loaded);
LoadComponentAsync(loaded, l =>
{
if (currentChannel.Messages.Any())
if (currentChannel.MessagesLoaded)
loading.Hide();
currentChannelContainer.Clear(false);
@ -394,6 +394,15 @@ namespace osu.Game.Overlays
{
careChannels.Add(channel);
channelTabs.AddItem(channel);
if (channel.Type == ChannelType.Public && !channel.Joined)
{
var req = new JoinChannelRequest(channel, api.LocalUser);
req.Success += () => addChannel(channel);
req.Failure += ex => removeChannel(channel);
api.Queue(req);
return;
}
}
// let's fetch a small number of messages to bring us up-to-date with the backlog.
@ -415,39 +424,45 @@ namespace osu.Game.Overlays
loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel));
channelTabs.RemoveItem(channel);
api.Queue(new LeaveChannelRequest(channel, api.LocalUser));
channel.Joined.Value = false;
}
private void fetchInitialMessages(Channel channel)
{
var req = new GetMessagesRequest(new List<Channel> { channel }, null);
req.Success += delegate (List<Message> messages)
var req = new GetMessagesRequest(channel);
req.Success += messages =>
{
loading.Hide();
channel.AddNewMessages(messages.ToArray());
Debug.Write("success!");
};
req.Failure += delegate
{
Debug.Write("failure!");
if (channel == currentChannel)
loading.Hide();
};
api.Queue(req);
}
private void fetchNewMessages()
private void fetchUpdates()
{
if (fetchReq != null) return;
fetchReq = new GetMessagesRequest(careChannels, lastMessageId);
fetchReq = new GetUpdatesRequest(lastMessageId);
fetchReq.Success += delegate (List<Message> messages)
fetchReq.Success += updates =>
{
foreach (var group in messages.Where(m => m.TargetType == TargetType.Channel).GroupBy(m => m.TargetId))
careChannels.Find(c => c.Id == group.Key)?.AddNewMessages(group.ToArray());
// fuck the what.
if (updates?.Presence != null)
{
foreach (var channel in updates.Presence)
{
channel.Joined.Value = true;
addChannel(channel);
}
lastMessageId = messages.LastOrDefault()?.Id ?? lastMessageId;
foreach (var group in updates.Messages.Where(m => m.TargetType == TargetType.Channel).GroupBy(m => m.TargetId))
careChannels.Find(c => c.Id == group.Key)?.AddNewMessages(group.ToArray());
lastMessageId = updates.Messages.LastOrDefault()?.Id ?? lastMessageId;
}
Debug.Write("success!");
fetchReq = null;

View File

@ -18,7 +18,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="ppy.osu.Framework" Version="0.0.7307" />
<PackageReference Include="ppy.osu.Framework" Version="2018.926.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.10.1" />
<PackageReference Include="SharpRaven" Version="2.4.0" />

View File

@ -218,6 +218,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GMT/@EntryIndexedValue">GMT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QAT/@EntryIndexedValue">QAT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BNG/@EntryIndexedValue">BNG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&#xD;
&lt;Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"&gt;&#xD;