From 31e26364a6c5dda84e294ff60e88820ef7c9d69f Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 01:47:24 +0200 Subject: [PATCH 1/9] Initial implementation of chat commands --- .../Online/API/Requests/PostMessageRequest.cs | 3 +- osu.Game/Online/Chat/Message.cs | 3 ++ osu.Game/Overlays/Chat/ChatLine.cs | 7 ++-- osu.Game/Overlays/ChatOverlay.cs | 33 ++++++++++++++++--- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/API/Requests/PostMessageRequest.cs b/osu.Game/Online/API/Requests/PostMessageRequest.cs index 52269d9fe8..f0c7cb9a9b 100644 --- a/osu.Game/Online/API/Requests/PostMessageRequest.cs +++ b/osu.Game/Online/API/Requests/PostMessageRequest.cs @@ -23,6 +23,7 @@ namespace osu.Game.Online.API.Requests req.Method = HttpMethod.POST; req.AddParameter(@"target_type", message.TargetType.GetDescription()); req.AddParameter(@"target_id", message.TargetId.ToString()); + req.AddParameter(@"is_action", message.IsAction.ToString().ToLower()); req.AddParameter(@"message", message.Content); return req; @@ -30,4 +31,4 @@ namespace osu.Game.Online.API.Requests protected override string Target => @"chat/messages"; } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index 509861868a..79b5c4fc1a 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -23,6 +23,9 @@ namespace osu.Game.Online.Chat [JsonProperty(@"target_id")] public int TargetId; + [JsonProperty(@"is_action")] + public bool IsAction; + [JsonProperty(@"timestamp")] public DateTimeOffset Timestamp; diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index cac0ce01ae..fc18049491 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -62,6 +62,7 @@ namespace osu.Game.Overlays.Chat public const float LEFT_PADDING = message_padding + padding * 2; private const float padding = 15; + private const float padding_action = 5; private const float message_padding = 200; private const float text_size = 20; @@ -183,7 +184,7 @@ namespace osu.Game.Overlays.Chat { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = message_padding + padding }, + Padding = new MarginPadding { Left = message_padding + (message.IsAction ? padding_action : padding) }, Children = new Drawable[] { contentFlow = new OsuTextFlowContainer(t => { t.TextSize = text_size; }) @@ -194,6 +195,8 @@ namespace osu.Game.Overlays.Chat } } }; + if (message.IsAction) + contentFlow.Colour = senderHasBackground ? OsuColour.FromHex(message.Sender.Colour) : username_colours[message.Sender.Id % username_colours.Length]; updateMessageContent(); FinishTransforms(true); @@ -205,7 +208,7 @@ namespace osu.Game.Overlays.Chat timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; - username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":"); + username.Text = (message.IsAction ? "*" : "") + $@"{message.Sender.Username}" + (senderHasBackground || message.IsAction ? "" : ":"); contentFlow.Text = message.Content; } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 7c28bdea4d..ef755b6239 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -465,7 +465,7 @@ namespace osu.Game.Overlays textbox.Text = string.Empty; - if (string.IsNullOrEmpty(postText)) + if (string.IsNullOrWhiteSpace(postText)) return; var target = currentChannel; @@ -478,11 +478,35 @@ namespace osu.Game.Overlays return; } + bool isAction = false; + if (postText[0] == '/') { - // TODO: handle commands - target.AddNewMessages(new ErrorMessage("Chat commands are not supported yet!")); - return; + postText = postText.Substring(1); + string commandKeyword = postText.Split(' ')[0]; + + switch (commandKeyword) + { + case "me": + + if (!postText.StartsWith("me ") || string.IsNullOrWhiteSpace(postText.Substring(3))) + { + currentChannel.AddNewMessages(new ErrorMessage("Usage: /me [action]")); + return; + } + + isAction = true; + postText = postText.Substring(3); + break; + + case "help": + currentChannel.AddNewMessages(new ErrorMessage("Supported commands: /help, /me [action]")); + return; + + default: + currentChannel.AddNewMessages(new ErrorMessage($@"""/{commandKeyword}"" is not supported! For a list of supported commands see /help")); + return; + } } var message = new LocalEchoMessage @@ -491,6 +515,7 @@ namespace osu.Game.Overlays Timestamp = DateTimeOffset.Now, TargetType = TargetType.Channel, //TODO: read this from channel TargetId = target.Id, + IsAction = isAction, Content = postText }; From dce577f92ae1bd61b6f536a24fe5fb61d2ad7694 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 11:30:01 +0200 Subject: [PATCH 2/9] Updated design --- osu.Game/Overlays/Chat/ChatLine.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index fc18049491..9345cd010e 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -62,8 +62,8 @@ namespace osu.Game.Overlays.Chat public const float LEFT_PADDING = message_padding + padding * 2; private const float padding = 15; - private const float padding_action = 5; private const float message_padding = 200; + private const float action_padding = 3; private const float text_size = 20; private Color4 customUsernameColour; @@ -184,7 +184,7 @@ namespace osu.Game.Overlays.Chat { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = message_padding + (message.IsAction ? padding_action : padding) }, + Padding = new MarginPadding { Left = message_padding + padding }, Children = new Drawable[] { contentFlow = new OsuTextFlowContainer(t => { t.TextSize = text_size; }) @@ -208,8 +208,14 @@ namespace osu.Game.Overlays.Chat timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; - username.Text = (message.IsAction ? "*" : "") + $@"{message.Sender.Username}" + (senderHasBackground || message.IsAction ? "" : ":"); - contentFlow.Text = message.Content; + username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":"); + + contentFlow.Clear(); + if (message.IsAction) + contentFlow.AddText("[", sprite => sprite.Padding = new MarginPadding { Right = action_padding }); + contentFlow.AddText(message.Content, sprite => sprite.Font = @"Exo2.0-MediumItalic" ); + if (message.IsAction) + contentFlow.AddText("]", sprite => sprite.Padding = new MarginPadding { Left = action_padding }); } private class MessageSender : ClickableContainer, IHasContextMenu From 3e8941f8e1662215901e8e5294feddbcca3dcedf Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 11:35:07 +0200 Subject: [PATCH 3/9] Fix chat message style for non action messages --- osu.Game/Overlays/Chat/ChatLine.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 9345cd010e..ef1ab5f9db 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -213,7 +213,11 @@ namespace osu.Game.Overlays.Chat contentFlow.Clear(); if (message.IsAction) contentFlow.AddText("[", sprite => sprite.Padding = new MarginPadding { Right = action_padding }); - contentFlow.AddText(message.Content, sprite => sprite.Font = @"Exo2.0-MediumItalic" ); + contentFlow.AddText(message.Content, sprite => + { + if (message.IsAction) + sprite.Font = @"Exo2.0-MediumItalic"; + }); if (message.IsAction) contentFlow.AddText("]", sprite => sprite.Padding = new MarginPadding { Left = action_padding }); } From dc5c046d4be5b2bb8f04f2105161fc09814b6f35 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 14:33:20 +0200 Subject: [PATCH 4/9] Fixed wrong action message color --- osu.Game/Overlays/Chat/ChatLine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index ef1ab5f9db..d17371fae1 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -195,8 +195,8 @@ namespace osu.Game.Overlays.Chat } } }; - if (message.IsAction) - contentFlow.Colour = senderHasBackground ? OsuColour.FromHex(message.Sender.Colour) : username_colours[message.Sender.Id % username_colours.Length]; + if (message.IsAction && senderHasBackground) + contentFlow.Colour = OsuColour.FromHex(message.Sender.Colour); updateMessageContent(); FinishTransforms(true); From 29707788f9dc62b76ea8c58644495f1a31b7b5c3 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 15:29:04 +0200 Subject: [PATCH 5/9] Code formatting --- osu.Game/Overlays/Chat/ChatLine.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index d17371fae1..4db6bdf5e4 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -210,16 +210,16 @@ namespace osu.Game.Overlays.Chat timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":"); - contentFlow.Clear(); if (message.IsAction) - contentFlow.AddText("[", sprite => sprite.Padding = new MarginPadding { Right = action_padding }); - contentFlow.AddText(message.Content, sprite => { - if (message.IsAction) - sprite.Font = @"Exo2.0-MediumItalic"; - }); - if (message.IsAction) + contentFlow.Clear(); + contentFlow.AddText("[", sprite => sprite.Padding = new MarginPadding { Right = action_padding }); + contentFlow.AddText(message.Content, sprite => sprite.Font = @"Exo2.0-MediumItalic"); contentFlow.AddText("]", sprite => sprite.Padding = new MarginPadding { Left = action_padding }); + } + else + contentFlow.Text = message.Content; + } private class MessageSender : ClickableContainer, IHasContextMenu From 18c26a85ba15af8213e3310f9501a4fecfd58551 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 15:30:07 +0200 Subject: [PATCH 6/9] Added an infoMessage class to represent system messages that aren't errors --- osu.Game/Online/Chat/ErrorMessage.cs | 17 ++++------------- osu.Game/Online/Chat/InfoMessage.cs | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 osu.Game/Online/Chat/InfoMessage.cs diff --git a/osu.Game/Online/Chat/ErrorMessage.cs b/osu.Game/Online/Chat/ErrorMessage.cs index 48557ca648..fdb77e328f 100644 --- a/osu.Game/Online/Chat/ErrorMessage.cs +++ b/osu.Game/Online/Chat/ErrorMessage.cs @@ -6,20 +6,11 @@ using osu.Game.Users; namespace osu.Game.Online.Chat { - public class ErrorMessage : Message + public class ErrorMessage : InfoMessage { - private static int errorId = -1; - - public ErrorMessage(string message) : base(errorId--) + public ErrorMessage(string message) : base(message) { - Timestamp = DateTimeOffset.Now; - Content = message; - - Sender = new User - { - Username = @"system", - Colour = @"ff0000", - }; + Sender.Colour = @"ff0000"; } } -} \ No newline at end of file +} diff --git a/osu.Game/Online/Chat/InfoMessage.cs b/osu.Game/Online/Chat/InfoMessage.cs new file mode 100644 index 0000000000..edadfe351d --- /dev/null +++ b/osu.Game/Online/Chat/InfoMessage.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Users; + +namespace osu.Game.Online.Chat +{ + public class InfoMessage : Message + { + private static int infoID = -1; + + public InfoMessage(string message) : base(infoID--) + { + Timestamp = DateTimeOffset.Now; + Content = message; + + Sender = new User + { + Username = @"system", + Colour = @"0000ff", + }; + } + } +} From 0a279167613a09ecae11c64908a103a8a9c94094 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 15:31:30 +0200 Subject: [PATCH 7/9] Added infoMessage class to the project, use the class for the /help command and handle command parameter better --- osu.Game/Overlays/ChatOverlay.cs | 17 ++++++++++++----- osu.Game/osu.Game.csproj | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index ef755b6239..93f8a3c2b7 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -482,25 +482,25 @@ namespace osu.Game.Overlays if (postText[0] == '/') { - postText = postText.Substring(1); - string commandKeyword = postText.Split(' ')[0]; + string unhandeledParameters = postText.Substring(1); + string commandKeyword = cutFirstParameter(ref unhandeledParameters); switch (commandKeyword) { case "me": - if (!postText.StartsWith("me ") || string.IsNullOrWhiteSpace(postText.Substring(3))) + if (string.IsNullOrWhiteSpace(unhandeledParameters)) { currentChannel.AddNewMessages(new ErrorMessage("Usage: /me [action]")); return; } isAction = true; - postText = postText.Substring(3); + postText = unhandeledParameters; break; case "help": - currentChannel.AddNewMessages(new ErrorMessage("Supported commands: /help, /me [action]")); + currentChannel.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action]")); return; default: @@ -528,6 +528,13 @@ namespace osu.Game.Overlays api.Queue(req); } + private string cutFirstParameter(ref string parameters) + { + string result = parameters.Split(' ')[0]; + parameters = result.Length == parameters.Length ? "" : parameters.Substring(result.Length + 1); + return result; + } + private void transformChatHeightTo(double newChatHeight, double duration = 0, Easing easing = Easing.None) { this.TransformTo(this.PopulateTransform(new TransformChatHeight(), newChatHeight, duration, easing)); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2d286fe1b8..1679c53ff9 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -372,6 +372,7 @@ + From 02bc42991179fb4409faa889d4400f110ea1700f Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 15:37:17 +0200 Subject: [PATCH 8/9] CI fix --- osu.Game/Online/Chat/ErrorMessage.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Online/Chat/ErrorMessage.cs b/osu.Game/Online/Chat/ErrorMessage.cs index fdb77e328f..0bf18fda39 100644 --- a/osu.Game/Online/Chat/ErrorMessage.cs +++ b/osu.Game/Online/Chat/ErrorMessage.cs @@ -1,9 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using osu.Game.Users; - namespace osu.Game.Online.Chat { public class ErrorMessage : InfoMessage From 34fb6ccdf5484c2a361f4977e48670a77ce83640 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 22 Sep 2017 16:17:03 +0200 Subject: [PATCH 9/9] Removed generic parameter function --- osu.Game/Overlays/ChatOverlay.cs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 93f8a3c2b7..24fc322199 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -482,21 +482,22 @@ namespace osu.Game.Overlays if (postText[0] == '/') { - string unhandeledParameters = postText.Substring(1); - string commandKeyword = cutFirstParameter(ref unhandeledParameters); + string[] parameters = postText.Substring(1).Split(new[] { ' ' }, 2); + string command = parameters[0]; + string content = parameters.Length == 2 ? parameters[1] : string.Empty; - switch (commandKeyword) + switch (command) { case "me": - if (string.IsNullOrWhiteSpace(unhandeledParameters)) + if (string.IsNullOrWhiteSpace(content)) { currentChannel.AddNewMessages(new ErrorMessage("Usage: /me [action]")); return; } isAction = true; - postText = unhandeledParameters; + postText = content; break; case "help": @@ -504,7 +505,7 @@ namespace osu.Game.Overlays return; default: - currentChannel.AddNewMessages(new ErrorMessage($@"""/{commandKeyword}"" is not supported! For a list of supported commands see /help")); + currentChannel.AddNewMessages(new ErrorMessage($@"""/{command}"" is not supported! For a list of supported commands see /help")); return; } } @@ -528,13 +529,6 @@ namespace osu.Game.Overlays api.Queue(req); } - private string cutFirstParameter(ref string parameters) - { - string result = parameters.Split(' ')[0]; - parameters = result.Length == parameters.Length ? "" : parameters.Substring(result.Length + 1); - return result; - } - private void transformChatHeightTo(double newChatHeight, double duration = 0, Easing easing = Easing.None) { this.TransformTo(this.PopulateTransform(new TransformChatHeight(), newChatHeight, duration, easing));