public void DisposeMessageGraphicsBuffer(Common.Message message) { if (message.buffer != null) { ((IDisposable)message.buffer).Dispose(); message.buffer = null; } }
protected virtual Message[] GetMessagesClone() { Message[] M; lock (MessageLock) { M = new Message[Messages.Length]; Array.Copy(Messages, M, M.Length); } return(M); }
public ChangelogControl(string md) { lock (MessageLock) { messages = Message.ParseMarkdown(md); } scrollAtBottom = false; updateMessageBounds(); AllowMessageSeperator = false; }
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); } } } } }
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); } }
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); }); }