Beispiel #1
0
 public void DisposeMessageGraphicsBuffer(Common.Message message)
 {
     if (message.buffer != null)
     {
         ((IDisposable)message.buffer).Dispose();
         message.buffer = null;
     }
 }
Beispiel #2
0
 protected virtual Message[] GetMessagesClone()
 {
     Message[] M;
     lock (MessageLock)
     {
         M = new Message[Messages.Length];
         Array.Copy(Messages, M, M.Length);
     }
     return(M);
 }
Beispiel #3
0
        public ChangelogControl(string md)
        {
            lock (MessageLock)
            {
                messages = Message.ParseMarkdown(md);
            }

            scrollAtBottom = false;

            updateMessageBounds();

            AllowMessageSeperator = false;
        }
Beispiel #4
0
        public void SetLastReadMessage()
        {
            if (MessageLock != null)
            {
                lock (MessageLock)
                {
                    if (Messages.Length != 0)
                    {
                        LastReadMessage = Messages[Messages.Length - 1];

                        _scroll.RemoveHighlightsWhere(highlight => highlight.Tag == lastReadMessageTag);

                        if (AppSettings.ChatShowLastReadMessageIndicator)
                        {
                            _scroll.AddHighlight(Messages.Length - 1, Color.Red, ScrollBarHighlightStyle.SingleLine,
                                                 lastReadMessageTag);
                        }
                    }
                }
            }
        }
Beispiel #5
0
        public static void DrawMessage(object graphics, Common.Message message, int xOffset, int yOffset,
                                       Selection selection, int currentLine, bool drawText, List <GifEmoteState> gifEmotesOnScreen = null,
                                       bool allowMessageSeperator = true)
        {
            message.X = xOffset;
            message.Y = yOffset;

            var g = (Graphics)graphics;

            var spaceWidth =
                GuiEngine.Current.MeasureStringSize(g, FontType.Medium, " ").Width;

            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.None;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            message.X = xOffset;
            var textColor = App.ColorScheme.Text;

            Brush highlightBrush = null;

            if (message.HasAnyHighlightType(HighlightType.Highlighted))
            {
                highlightBrush = App.ColorScheme.ChatBackgroundHighlighted;
            }
            else if (message.HasAnyHighlightType(HighlightType.Resub))
            {
                highlightBrush = App.ColorScheme.ChatBackgroundResub;
            }
            else if (message.HasAnyHighlightType(HighlightType.Whisper))
            {
                highlightBrush = App.ColorScheme.ChatBackgroundWhisper;
            }

            if (highlightBrush != null)
            {
                g.FillRectangle(highlightBrush, 0, yOffset, g.ClipBounds.Width, message.Height);
            }

            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;

            for (var i = 0; i < message.Words.Count; i++)
            {
                var word = message.Words[i];

                if (word.Type == SpanType.Text)
                {
                    if (drawText)
                    {
                        var font = Fonts.GetFont(word.Font);

                        var color = textColor;

                        if (word.Color.HasValue)
                        {
                            var hsl = word.Color.Value;

                            if (App.ColorScheme.IsLightTheme)
                            {
                                if (hsl.Luminosity > 0.5f)
                                {
                                    hsl = hsl.WithLuminosity(0.5f);
                                }
                            }
                            else
                            {
                                if (hsl.Luminosity < 0.3f)
                                {
                                    hsl = hsl.WithLuminosity(0.3f);
                                }
                            }

                            float r, _g, b;
                            hsl.ToRGB(out r, out _g, out b);
                            color = Color.FromArgb((int)(r * 255), (int)(_g * 255), (int)(b * 255));
                        }

                        if (word.SplitSegments == null)
                        {
                            TextRenderer.DrawText(g, (string)word.Value, font,
                                                  new Point(xOffset + word.X, yOffset + word.Y), color, App.DefaultTextFormatFlags);
                        }
                        else
                        {
                            var segments = word.SplitSegments;
                            for (var x = 0; x < segments.Length; x++)
                            {
                                TextRenderer.DrawText(g, segments[x].Item1, font,
                                                      new Point(xOffset + segments[x].Item2.X, yOffset + segments[x].Item2.Y), color,
                                                      App.DefaultTextFormatFlags);
                            }
                        }
                    }
                }
                else if (word.Type == SpanType.LazyLoadedImage)
                {
                    var emote = (LazyLoadedImage)word.Value;
                    var img   = (Image)emote.Image;
                    if (img != null)
                    {
                        lock (img)
                        {
                            g.DrawImage(img, word.X + xOffset, word.Y + yOffset, word.Width, word.Height);
                        }
                    }
                    else
                    {
                        //g.DrawRectangle(Pens.Red, xOffset + word.X, word.Y + yOffset, word.Width, word.Height);
                    }
                }
                //else if (word.Type == SpanType.Image)
                //{
                //    var img = (Image)word.Value;
                //    if (img != null)
                //        g.DrawImage(img, word.X + xOffset, word.Y + yOffset, word.Width, word.Height);
                //}
            }

            Action <int, bool> addWordToGifList = (i, selected) =>
            {
                var word  = message.Words[i];
                var words = new List <Word>();

                for (var j = i - 1; j >= 0; j--)
                {
                    if (message.Words[j].Intersects(word))
                    {
                        words.Insert(0, message.Words[j]);
                    }
                    else
                    {
                        break;
                    }
                }

                words.Add(word);

                for (var j = i + 1; j < message.Words.Count; j++)
                {
                    if (message.Words[j].Intersects(word))
                    {
                        words.Add(message.Words[j]);
                    }
                    else
                    {
                        break;
                    }
                }

                gifEmotesOnScreen?.Add(new GifEmoteState(word.X + xOffset, word.Y + yOffset, word.Width, word.Height, words, selected, message.HighlightType, message.Disabled, yOffset, xOffset));
            };

            if (selection != null && !selection.IsEmpty && selection.First.MessageIndex <= currentLine &&
                selection.Last.MessageIndex >= currentLine)
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;

                var first = selection.First;
                var last  = selection.Last;
                for (var i = 0; i < message.Words.Count; i++)
                {
                    var word = message.Words[i];

                    if ((currentLine != first.MessageIndex || i >= first.WordIndex) &&
                        (currentLine != last.MessageIndex || i <= last.WordIndex))
                    {
                        if (word.Type == SpanType.Text)
                        {
                            for (var j = 0; j < (word.SplitSegments?.Length ?? 1); j++)
                            {
                                if ((first.MessageIndex == currentLine && first.WordIndex == i && first.SplitIndex > j) ||
                                    (last.MessageIndex == currentLine && last.WordIndex == i && last.SplitIndex < j))
                                {
                                    continue;
                                }

                                var split = word.SplitSegments?[j];
                                var text  = split?.Item1 ?? (string)word.Value;
                                var rect  = split?.Item2 ??
                                            new CommonRectangle(word.X, word.Y, word.Width, word.Height);

                                var textLength = text.Length;

                                var offset = (first.MessageIndex == currentLine && first.SplitIndex == j &&
                                              first.WordIndex == i)
                                    ? first.CharIndex
                                    : 0;
                                var length = ((last.MessageIndex == currentLine && last.SplitIndex == j &&
                                               last.WordIndex == i)
                                                 ? last.CharIndex
                                                 : textLength) - offset;

                                if (offset == 0 && length == text.Length)
                                {
                                    g.FillRectangle(_selectionBrush, rect.X + xOffset, rect.Y + yOffset,
                                                    GuiEngine.Current.MeasureStringSize(App.UseDirectX ? null : g, word.Font, text)
                                                    .Width + spaceWidth - 1, rect.Height);
                                }
                                else if (offset == text.Length)
                                {
                                    g.FillRectangle(_selectionBrush, rect.X + xOffset + rect.Width, rect.Y + yOffset,
                                                    spaceWidth, rect.Height);
                                }
                                else
                                {
                                    g.FillRectangle(_selectionBrush,
                                                    rect.X + xOffset +
                                                    (offset == 0
                                            ? 0
                                            : GuiEngine.Current.MeasureStringSize(App.UseDirectX ? null : g, word.Font,
                                                                                  text.Remove(offset)).Width),
                                                    rect.Y + yOffset,
                                                    GuiEngine.Current.MeasureStringSize(App.UseDirectX ? null : g, word.Font,
                                                                                        text.Substring(offset, length)).Width +
                                                    ((last.MessageIndex > currentLine || last.SplitIndex > j || last.WordIndex > i)
                                            ? spaceWidth
                                            : 0),
                                                    rect.Height);
                                }
                            }
                        }
                        //else if (word.Type == SpanType.Image)
                        //{
                        //    var textLength = 2;

                        //    var offset = (first.MessageIndex == currentLine && first.WordIndex == i)
                        //        ? first.CharIndex
                        //        : 0;
                        //    var length = ((last.MessageIndex == currentLine && last.WordIndex == i)
                        //                     ? last.CharIndex
                        //                     : textLength) - offset;

                        //    g.FillRectangle(_selectionBrush, word.X + xOffset + (offset == 0 ? 0 : word.Width),
                        //        word.Y + yOffset,
                        //        (offset == 0 ? word.Width : 0) + (offset + length == 2 ? spaceWidth : 0) - 1,
                        //        word.Height);
                        //}
                        else if (word.Type == SpanType.LazyLoadedImage)
                        {
                            var textLength = 2;

                            var offset = (first.MessageIndex == currentLine && first.WordIndex == i)
                                ? first.CharIndex
                                : 0;
                            var length = ((last.MessageIndex == currentLine && last.WordIndex == i)
                                             ? last.CharIndex
                                             : textLength) - offset;

                            var emote = (LazyLoadedImage)word.Value;

                            if (emote.IsAnimated)
                            {
                                addWordToGifList(i, true);
                            }
                            else
                            {
                                g.FillRectangle(_selectionBrush, word.X + xOffset, word.Y + yOffset,
                                                word.Width + spaceWidth - 1, word.Height);
                            }
                        }
                    }
                    else
                    {
                        if (word.Type == SpanType.LazyLoadedImage)
                        {
                            var emote = (LazyLoadedImage)word.Value;
                            if (emote.IsAnimated)
                            {
                                addWordToGifList(i, true);
                            }
                        }
                    }
                }
            }
            else
            {
                for (int i = 0; i < message.Words.Count; i++)
                {
                    var word = message.Words[i];
                    if (word.Type == SpanType.LazyLoadedImage)
                    {
                        var emote = (LazyLoadedImage)word.Value;
                        if (emote.IsAnimated)
                        {
                            addWordToGifList(i, false);
                        }
                    }
                }
            }

            if (allowMessageSeperator && AppSettings.ChatSeperateMessages)
            {
                g.DrawLine(App.ColorScheme.ChatMessageSeperatorBorder, 0, yOffset + 1, message.Width + 128, yOffset + 1);
                g.DrawLine(App.ColorScheme.ChatMessageSeperatorBorderInner, 0, yOffset, message.Width + 128, yOffset);
            }

            if (message.HasAnyHighlightType(HighlightType.SearchResult))
            {
                g.FillRectangle(Brushes.GreenYellow, 1, yOffset, 1, message.Height - 1);
            }
        }
Beispiel #6
0
        public static void addChatCommands()
        {
            Commands.ChatCommands.TryAdd("user", (s, channel, execute) =>
            {
                if (execute)
                {
                    var S = s.SplitWords();
                    if (S.Length > 0 && S[0].Length > 0)
                    {
                        Common.UserInfoData data = new Common.UserInfoData();
                        data.UserName            = S[0];
                        data.Channel             = channel;
                        if ((data.UserId = IrcManager.LoadUserIDFromTwitch(data.UserName)) != null)
                        {
                            var popup = new UserInfoPopup(data)
                            {
                                StartPosition = FormStartPosition.Manual,
                                Location      = Cursor.Position
                            };

                            popup.Show();

                            var screen = Screen.FromPoint(Cursor.Position);

                            int x = popup.Location.X, y = popup.Location.Y;

                            if (popup.Location.X < screen.WorkingArea.X)
                            {
                                x = screen.WorkingArea.X;
                            }
                            else if (popup.Location.X + popup.Width > screen.WorkingArea.Right)
                            {
                                x = screen.WorkingArea.Right - popup.Width;
                            }

                            if (popup.Location.Y < screen.WorkingArea.Y)
                            {
                                y = screen.WorkingArea.Y;
                            }
                            else if (popup.Location.Y + popup.Height > screen.WorkingArea.Bottom)
                            {
                                y = screen.WorkingArea.Bottom - popup.Height;
                            }

                            popup.Location = new Point(x, y);
                        }
                        else
                        {
                            channel.AddMessage(new Chatterino.Common.Message($"This user could not be found (/user {data.UserName})"));
                        }
                    }
                }
                return(null);
            });

            // Chat Commands
            Commands.ChatCommands.TryAdd("w", (s, channel, execute) =>
            {
                if (execute)
                {
                    var S = s.SplitWords();

                    if (S.Length > 1)
                    {
                        var name = S[0];

                        IrcMessage message;
                        IrcMessage.TryParse($":{name}!{name}@{name}.tmi.twitch.tv PRIVMSG #whispers :" + s.SubstringFromWordIndex(1), out message);

                        TwitchChannel.WhisperChannel.AddMessage(new Chatterino.Common.Message(message, TwitchChannel.WhisperChannel, isSentWhisper: true));

                        if (AppSettings.ChatEnableInlineWhispers)
                        {
                            var inlineMessage = new Chatterino.Common.Message(message, TwitchChannel.WhisperChannel, true, false, isSentWhisper: true)
                            {
                                HighlightTab = false
                            };

                            inlineMessage.HighlightType = HighlightType.Whisper;

                            foreach (var c in TwitchChannel.Channels)
                            {
                                c.AddMessage(inlineMessage);
                            }
                        }
                    }
                }

                return("/w " + s);
            });

            Commands.ChatCommands.TryAdd("ignore", (s, channel, execute) =>
            {
                if (execute)
                {
                    var S = s.SplitWords();
                    if (S.Length > 0)
                    {
                        IrcManager.AddIgnoredUser(S[0], null);
                    }
                }
                return(null);
            });
            Commands.ChatCommands.TryAdd("rejoin", (s, channel, execute) =>
            {
                if (execute)
                {
                    Task.Run(() =>
                    {
                        channel.Rejoin();
                    });
                }
                return(null);
            });
            Commands.ChatCommands.TryAdd("unignore", (s, channel, execute) =>
            {
                if (execute)
                {
                    var S = s.SplitWords();
                    if (S.Length > 0)
                    {
                        IrcManager.RemoveIgnoredUser(S[0], null);
                    }
                }
                return(null);
            });

            Commands.ChatCommands.TryAdd("uptime", (s, channel, execute) =>
            {
                if (execute && channel != null)
                {
                    try
                    {
                        var request =
                            WebRequest.Create(
                                $"https://api.twitch.tv/helix/streams?user_login={channel.Name}");
                        if (AppSettings.IgnoreSystemProxy)
                        {
                            request.Proxy = null;
                        }
                        request.Headers["Authorization"] = $"Bearer {IrcManager.Account.OauthToken}";
                        request.Headers["Client-ID"]     = $"{IrcManager.DefaultClientID}";
                        using (var resp = request.GetResponse())
                            using (var stream = resp.GetResponseStream())
                            {
                                var parser = new JsonParser();

                                dynamic json = parser.Parse(stream);
                                dynamic data = json["data"];
                                if (data != null && data.Count > 0 && data[0]["type"] != "")
                                {
                                    dynamic root = data[0];

                                    string createdAt = root["started_at"];

                                    var streamStart = DateTime.Parse(createdAt);

                                    var uptime = DateTime.Now - streamStart;

                                    var text = "Stream uptime: ";

                                    if (uptime.TotalDays > 1)
                                    {
                                        text += (int)uptime.TotalDays + " days, " + uptime.ToString("hh\\h\\ mm\\m\\ ss\\s");
                                    }
                                    else
                                    {
                                        text += uptime.ToString("hh\\h\\ mm\\m\\ ss\\s");
                                    }

                                    channel.AddMessage(new Chatterino.Common.Message(text));
                                }
                            }
                    }
                    catch { }
                }

                return(null);
            });
        }