Пример #1
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);
            }
        }
Пример #2
0
        private static void ReadConnection_MessageReceived(object sender, MessageEventArgs e)
        {
            var msg = e.Message;

            if (msg.Command == "PRIVMSG")
            {
                TwitchChannel.GetChannel(msg.Middle.TrimStart('#')).Process(c =>
                {
                    if (msg.PrefixUser == "twitchnotify")
                    {
                        c.AddMessage(new Message(msg.Params ?? "", HSLColor.Gray, true)
                        {
                            HighlightType = HighlightType.Resub
                        });
                    }
                    else
                    {
                        // check if ignore keyword is triggered
                        if (AppSettings.IgnoredKeywordsRegex == null || !AppSettings.IgnoredKeywordsRegex.IsMatch(e.Message.Params))
                        {
                            var message = new Message(msg, c);

                            // check if user is on the ignore list
                            if (AppSettings.EnableTwitchUserIgnores && IsIgnoredUser(message.Username))
                            {
                                switch (AppSettings.ChatShowIgnoredUsersMessages)
                                {
                                case 1:
                                    if (!c.IsModOrBroadcaster)
                                    {
                                        return;
                                    }
                                    break;

                                case 2:
                                    if (!c.IsBroadcaster)
                                    {
                                        return;
                                    }
                                    break;

                                default:
                                    return;
                                }
                            }

                            {
                                c.Users[message.Username.ToUpper()] = message.DisplayName;

                                if (message.HasAnyHighlightType(HighlightType.Highlighted))
                                {
                                    var mentionMessage = new Message(msg, c, enablePingSound: false, includeChannel: true)
                                    {
                                        HighlightType = HighlightType.None
                                    };

                                    TwitchChannel.MentionsChannel.AddMessage(mentionMessage);
                                }

                                c.AddMessage(message);
                            }
                        }
                    }
                });
            }
            else if (msg.Command == "CLEARCHAT")
            {
                var channel = msg.Middle;
                var user    = msg.Params;

                string reason;
                msg.Tags.TryGetValue("ban-reason", out reason);
                string _duration;
                var    duration = 0;

                if (msg.Tags.TryGetValue("ban-duration", out _duration))
                {
                    int.TryParse(_duration, out duration);
                }

                TwitchChannel.GetChannel((msg.Middle ?? "").TrimStart('#')).Process(c => c.ClearChat(user, reason, duration));
                //}
            }
            else if (msg.Command == "ROOMSTATE")
            {
                TwitchChannel.GetChannel((msg.Middle ?? "").TrimStart('#')).Process(c =>
                {
                    var state = c.RoomState;

                    string value;
                    if (msg.Tags.TryGetValue("emote-only", out value))
                    {
                        if (value == "1")
                        {
                            state |= RoomState.EmoteOnly;
                        }
                        else
                        {
                            state &= ~RoomState.EmoteOnly;
                        }
                    }
                    if (msg.Tags.TryGetValue("subs-only", out value))
                    {
                        if (value == "1")
                        {
                            state |= RoomState.SubOnly;
                        }
                        else
                        {
                            state &= ~RoomState.SubOnly;
                        }
                    }
                    if (msg.Tags.TryGetValue("slow", out value))
                    {
                        if (value == "0")
                        {
                            state &= ~RoomState.SlowMode;
                        }
                        else
                        {
                            int time;
                            if (!int.TryParse(value, out time))
                            {
                                time = -1;
                            }
                            c.SlowModeTime = time;
                            state         |= RoomState.SlowMode;
                        }
                    }
                    if (msg.Tags.TryGetValue("r9k", out value))
                    {
                        if (value == "1")
                        {
                            state |= RoomState.R9k;
                        }
                        else
                        {
                            state &= ~RoomState.R9k;
                        }
                    }
                    //if (e.Data.Tags.TryGetValue("broadcaster-lang", out value))

                    c.RoomState = state;
                });
            }
            else if (msg.Command == "USERSTATE")
            {
                string value;

                if (msg.Tags.TryGetValue("mod", out value))
                {
                    TwitchChannel.GetChannel((msg.Middle ?? "").TrimStart('#')).Process(c => c.IsMod = value == "1");
                }
            }
            else if (msg.Command == "WHISPER")
            {
                TwitchChannel.WhisperChannel.AddMessage(new Message(msg, TwitchChannel.WhisperChannel, true, false, isReceivedWhisper: true));

                LastReceivedWhisperUser = msg.PrefixUser;

                if (AppSettings.ChatEnableInlineWhispers)
                {
                    var inlineMessage = new Message(msg, TwitchChannel.WhisperChannel, true, false, true)
                    {
                        HighlightTab  = false,
                        HighlightType = HighlightType.Whisper
                    };

                    foreach (var channel in TwitchChannel.Channels)
                    {
                        channel.AddMessage(inlineMessage);
                    }
                }
            }
            else if (msg.Command == "USERNOTICE")
            {
                string sysMsg;
                msg.Tags.TryGetValue("system-msg", out sysMsg);

                TwitchChannel.GetChannel((msg.Middle ?? "").TrimStart('#')).Process(c =>
                {
                    try
                    {
                        var sysMessage = new Message(sysMsg, HSLColor.Gray, true)
                        {
                            HighlightType = HighlightType.Resub
                        };
                        c.AddMessage(sysMessage);

                        if (!string.IsNullOrEmpty(msg.Params))
                        {
                            var message = new Message(msg, c)
                            {
                                HighlightType = HighlightType.Resub
                            };
                            c.AddMessage(message);
                        }
                    }
                    catch { }
                });
            }
        }