From 28045b71369ca5f3ae15c24a118f43a445c84bb1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 27 Sep 2016 18:31:36 +0900 Subject: [PATCH] Add back basic API support for channel/message retrieval. --- .../Tests/TestCaseChatDisplay.cs | 128 ++++++++++++++++++ .../osu.Desktop.VisualTests.csproj | 1 + osu.Game/Online/API/APIAccess.cs | 18 +-- osu.Game/Online/API/APIRequest.cs | 12 +- .../Online/API/Requests/GetMessagesRequest.cs | 2 +- osu.Game/Online/API/Requests/ListChannels.cs | 2 +- osu.Game/Online/Chat/Message.cs | 2 +- osu.Game/Online/User.cs | 16 +++ osu.Game/OsuGame.cs | 8 -- osu.Game/OsuGameBase.cs | 11 +- osu.Game/osu.Game.csproj | 1 + 11 files changed, 174 insertions(+), 27 deletions(-) create mode 100644 osu.Desktop.VisualTests/Tests/TestCaseChatDisplay.cs create mode 100644 osu.Game/Online/User.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseChatDisplay.cs b/osu.Desktop.VisualTests/Tests/TestCaseChatDisplay.cs new file mode 100644 index 0000000000..3063c8104b --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseChatDisplay.cs @@ -0,0 +1,128 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.GameModes.Testing; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Transformations; +using osu.Framework.Threading; +using osu.Game; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.Chat; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace osu.Desktop.Tests +{ + class TestCaseChatDisplay : TestCase + { + private ScheduledDelegate messageRequest; + + public override string Name => @"Chat"; + public override string Description => @"Testing API polling"; + + List channels = new List(); + private FlowContainer flow; + + Scheduler scheduler = new Scheduler(); + + private APIAccess api => ((OsuGameBase)Game).API; + + public override void Reset() + { + base.Reset(); + + flow = new FlowContainer() + { + Direction = FlowDirection.VerticalOnly, + LayoutDuration = 100, + LayoutEasing = EasingTypes.Out, + Padding = new Vector2(1, 1) + }; + + + lastMessageId = null; + + if (api.State != APIAccess.APIState.Online) + api.OnStateChange += delegate { initializeChannels(); }; + else + initializeChannels(); + + + ScrollContainer scrolling = new ScrollContainer() + { + Size = new Vector2(1, 0.5f) + }; + + scrolling.Add(flow); + Add(scrolling); + } + + protected override void Update() + { + scheduler.Update(); + base.Update(); + } + + private void initializeChannels() + { + if (api.State != APIAccess.APIState.Online) + return; + + messageRequest?.Cancel(); + + ListChannelsRequest req = new ListChannelsRequest(); + req.Success += delegate (List channels) + { + this.channels = channels; + messageRequest = scheduler.AddDelayed(requestNewMessages, 1000, true); + }; + api.Queue(req); + } + + long? lastMessageId = null; + + private void requestNewMessages() + { + messageRequest.Wait(); + + Channel channel = channels.Find(c => c.Name == "#osu"); + + GetMessagesRequest gm = new GetMessagesRequest(new List { channel }, lastMessageId); + gm.Success += delegate (List messages) + { + foreach (Message m in messages) + { + //m.LineWidth = this.Size.X; //this is kinda ugly. + //m.Drawable.Depth = m.Id; + //m.Drawable.FadeInFromZero(800); + + //flow.Add(m.Drawable); + + //if (osu.Messages.Count > 50) + //{ + // osu.Messages[0].Drawable.Expire(); + // osu.Messages.RemoveAt(0); + //} + + channel.Messages.Add(m); + } + + lastMessageId = messages.LastOrDefault()?.Id ?? lastMessageId; + + Debug.Write("success!"); + messageRequest.Continue(); + }; + gm.Failure += delegate + { + Debug.Write("failure!"); + messageRequest.Continue(); + }; + + api.Queue(gm); + } + } +} diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 22946a6433..2291150b9b 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -150,6 +150,7 @@ + diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 59b3d91d51..1ecad1bb71 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -10,11 +10,11 @@ using osu.Game.Online.API.Requests; namespace osu.Game.Online.API { - internal class APIAccess + public class APIAccess { private OAuth authentication; - internal string Endpoint = @"https://new.ppy.sh"; + public string Endpoint = @"https://new.ppy.sh"; const string ClientId = @"daNBnfdv7SppRVc61z0XuOI13y6Hroiz"; const string ClientSecret = @"d6fgZuZeQ0eSXkEj5igdqQX6ztdtS6Ow"; @@ -52,7 +52,7 @@ namespace osu.Game.Online.API Logger log; - internal APIAccess() + public APIAccess() { authentication = new OAuth(ClientId, ClientSecret, Endpoint); log = Logger.GetLogger(LoggingTarget.Network); @@ -61,7 +61,7 @@ namespace osu.Game.Online.API thread.Start(); } - internal string AccessToken => authentication.RequestAccessToken(); + public string AccessToken => authentication.RequestAccessToken(); /// /// Number of consecutive requests which failed due to network issues. @@ -221,16 +221,16 @@ namespace osu.Game.Online.API } } - internal void Queue(APIRequest request) + public void Queue(APIRequest request) { queue.Enqueue(request); } - internal event StateChangeDelegate OnStateChange; + public event StateChangeDelegate OnStateChange; - internal delegate void StateChangeDelegate(APIState oldState, APIState newState); + public delegate void StateChangeDelegate(APIState oldState, APIState newState); - internal enum APIState + public enum APIState { /// /// We cannot login (not enough credentials). @@ -268,7 +268,7 @@ namespace osu.Game.Online.API } } - internal void Logout() + public void Logout() { authentication.Clear(); State = APIState.Offline; diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index 3de942b998..3eada96417 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -11,7 +11,7 @@ namespace osu.Game.Online.API /// An API request with a well-defined response type. /// /// Type of the response (used for deserialisation). - internal class APIRequest : APIRequest + public class APIRequest : APIRequest { protected override WebRequest CreateWebRequest() => new JsonWebRequest(Uri); @@ -36,7 +36,7 @@ namespace osu.Game.Online.API /// /// The maximum amount of time before this request will fail. /// - internal int Timeout = WebRequest.DEFAULT_TIMEOUT; + public int Timeout = WebRequest.DEFAULT_TIMEOUT; protected virtual string Target => string.Empty; @@ -46,11 +46,11 @@ namespace osu.Game.Online.API private double remainingTime => Math.Max(0, Timeout - (DateTime.Now.TotalMilliseconds() - (startTime ?? 0))); - internal bool ExceededTimeout => remainingTime == 0; + public bool ExceededTimeout => remainingTime == 0; private double? startTime; - internal double StartTime => startTime ?? -1; + public double StartTime => startTime ?? -1; private APIAccess api; protected WebRequest WebRequest; @@ -58,7 +58,7 @@ namespace osu.Game.Online.API public event APISuccessHandler Success; public event APIFailureHandler Failure; - internal void Perform(APIAccess api) + public void Perform(APIAccess api) { if (startTime == null) startTime = DateTime.Now.TotalMilliseconds(); @@ -79,7 +79,7 @@ namespace osu.Game.Online.API //}); } - internal void Fail(Exception e) + public void Fail(Exception e) { WebRequest?.Abort(); //OsuGame.Scheduler.Add(delegate { diff --git a/osu.Game/Online/API/Requests/GetMessagesRequest.cs b/osu.Game/Online/API/Requests/GetMessagesRequest.cs index 4de206e8c0..96ded02d55 100644 --- a/osu.Game/Online/API/Requests/GetMessagesRequest.cs +++ b/osu.Game/Online/API/Requests/GetMessagesRequest.cs @@ -7,7 +7,7 @@ using osu.Game.Online.Chat; namespace osu.Game.Online.API.Requests { - internal class GetMessagesRequest : APIRequest> + public class GetMessagesRequest : APIRequest> { List channels; long? since; diff --git a/osu.Game/Online/API/Requests/ListChannels.cs b/osu.Game/Online/API/Requests/ListChannels.cs index 5592f8aa04..ecee48a938 100644 --- a/osu.Game/Online/API/Requests/ListChannels.cs +++ b/osu.Game/Online/API/Requests/ListChannels.cs @@ -6,7 +6,7 @@ using osu.Game.Online.Chat; namespace osu.Game.Online.API.Requests { - internal class ListChannelsRequest : APIRequest> + public class ListChannelsRequest : APIRequest> { protected override string Target => @"chat/channels"; } diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index ecf91c481d..28e6a89037 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -24,7 +24,7 @@ namespace osu.Game.Online.Chat internal string Content; [JsonProperty(@"sender")] - internal string User; + internal User User; [JsonConstructor] public Message() diff --git a/osu.Game/Online/User.cs b/osu.Game/Online/User.cs new file mode 100644 index 0000000000..27de5d8dc2 --- /dev/null +++ b/osu.Game/Online/User.cs @@ -0,0 +1,16 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; + +namespace osu.Game.Online +{ + public class User + { + [JsonProperty(@"username")] + public string Name; + + [JsonProperty(@"colour")] + public string Colour; + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 22c8e079a4..1230984ce0 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -25,14 +25,6 @@ namespace osu.Game Add(new MainMenu()); } - protected override void Dispose(bool isDisposing) - { - //refresh token may have changed. - Config.Set(OsuConfig.Token, API.Token); - - base.Dispose(isDisposing); - } - public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { if (!base.Invalidate(invalidation, source, shallPropagate)) return false; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index c9398b15b7..8561c0124d 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -15,7 +15,7 @@ namespace osu.Game protected override string MainResourceFile => @"osu.Game.Resources.dll"; - internal APIAccess API; + public APIAccess API; protected override Container AddTarget => ratioContainer?.IsLoaded == true ? ratioContainer : base.AddTarget; @@ -49,5 +49,14 @@ namespace osu.Game } }); } + + protected override void Dispose(bool isDisposing) + { + //refresh token may have changed. + Config.Set(OsuConfig.Token, API.Token); + Config.Save(); + + base.Dispose(isDisposing); + } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 34f7b3801b..0d20b265cf 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -62,6 +62,7 @@ +