Beispiel #1
0
        /// <summary>
        ///     Handles banning users that user non-ascii characters.
        /// </summary>
        /// <param name="config">The configuration for the twitch chat.</param>
        /// <param name="client">The twitch client.</param>
        /// <param name="messageInfo">The information on the chat message.</param>
        /// <returns>True if the message should be passed on, false if it should be discarded.</returns>
        public bool Handle(TwitchChatConfiguration config, TwitchClient client, OnMessageReceivedArgs messageInfo)
        {
            string chatMessage = messageInfo.ChatMessage.Message;

            // First convert each character into their hex-sequence representation in Unicode. This will catch both
            // characters outside of the ASCII character set (> 127) and non-emojis. We only allow ASCII characters
            // and emojis.
            var convertedMessageCharacters = UnicodeUtilities.ConvertToUnicodeNumber(chatMessage);

            foreach (var character in convertedMessageCharacters)
            {
                // If there is no space, then just evaluate the single character.
                if (!character.Contains(" "))
                {
                    var num = int.Parse(character, NumberStyles.HexNumber);
                    if (num > 127 && !UnicodeUtilities.IsEmoji(character))
                    {
                        return(false);
                    }

                    continue;
                }

                // If there is a space, it can only possibly be an emoji to be valid.
                if (!UnicodeUtilities.IsEmoji(character))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #2
0
        static bool IsWord(ITextSnapshot snapshot, int position, int length)
        {
            bool valid = position >= 0 && length >= 0 && (uint)(position + length) <= (uint)snapshot.Length;

            Debug.Assert(valid);
            if (!valid)
            {
                return(false);
            }
            var line = snapshot.GetLineFromPosition(position);

            return(UnicodeUtilities.IsWord(line, position - line.Start.Position, length));
        }
Beispiel #3
0
        IEnumerable <FindResult> FindAllSingleLineReverse(ITextSnapshotLine startLine, ITextSnapshotLine endLine, SnapshotSpan searchRange, string searchPattern, FindOptions options, StringComparison stringComparison, string replacePattern)
        {
            Debug.Assert((options & FindOptions.SearchReverse) != 0);
            int  startLineNumber = startLine.LineNumber;
            var  snapshot        = searchRange.Snapshot;
            bool onlyWords       = (options & FindOptions.WholeWord) != 0;
            var  regex           = (options & FindOptions.UseRegularExpressions) != 0 ? GetRegex(searchPattern, options) : null;

            for (int lineNumber = endLine.LineNumber; lineNumber >= startLineNumber; lineNumber--)
            {
                var line  = snapshot.GetLineFromLineNumber(lineNumber);
                var range = searchRange.Intersection(line.ExtentIncludingLineBreak);
                if (range == null || range.Value.Length == 0)
                {
                    continue;
                }
                var text  = range.Value.GetText();
                int index = text.Length;
                if (regex != null)
                {
                    foreach (var res in GetRegexResults(regex, range.Value.Start, text, index, searchPattern, options, replacePattern))
                    {
                        yield return(res);
                    }
                }
                else
                {
                    while (index > 0)
                    {
                        index = text.LastIndexOf(searchPattern, index - 1, index, stringComparison);
                        if (index < 0)
                        {
                            break;
                        }
                        if (!onlyWords || UnicodeUtilities.IsWord(line, range.Value.Start.Position - line.Start.Position + index, searchPattern.Length))
                        {
                            yield return(new FindResult(range.Value.Start.Position + index, searchPattern.Length, replacePattern));
                        }
                        index += searchPattern.Length - 1;
                    }
                }
            }
        }
Beispiel #4
0
        bool CollectEof(ICancellable cnc, TextData td, Rect clip_rect, int top_index)
        {
            if (cnc.IsCancellationRequested)
            {
                return(false);
            }

            var rtb = Rtb;

            double max_x    = double.NaN;
            Rect   end_rect = Rect.Empty;

            UITaskHelper.Invoke(rtb,
                                () =>
            {
                var end  = rtb.Document.ContentEnd;
                end_rect = end.GetCharacterRect(LogicalDirection.Forward);                           // (no width)

                if (end_rect.Bottom < clip_rect.Top || end_rect.Top > clip_rect.Bottom)
                {
                    return;
                }

                max_x = end_rect.Left;

                // if no RTL, then return a quick answer

                var begin_line = end.GetLineStartPosition(0);
                if (begin_line != null)
                {
                    var r        = new TextRange(begin_line, end);
                    var text     = r.Text;
                    bool has_RTL = false;

                    for (int k = 0; k < text.Length; ++k)
                    {
                        if (cnc.IsCancellationRequested)
                        {
                            return;
                        }

                        if (UnicodeUtilities.IsRTL(text[k]))
                        {
                            has_RTL = true;
                            break;
                        }
                    }

                    if (!has_RTL)
                    {
                        return;
                    }
                }

                // we have RTL segments that need additional navigation to find the rightmost X

                for (var tp = end; ;)
                {
                    if (cnc.IsCancellationRequested)
                    {
                        return;
                    }

                    tp = tp.GetNextInsertionPosition(LogicalDirection.Backward);
                    if (tp == null)
                    {
                        break;
                    }

                    // WORKAROUND for lines like "0ראל", when "0" is matched and highlighted
                    tp = tp.GetInsertionPosition(LogicalDirection.Forward);

                    var rect = tp.GetCharacterRect(LogicalDirection.Forward);
                    if (rect.Bottom < end_rect.Bottom)
                    {
                        break;
                    }

                    if (max_x < rect.Left)
                    {
                        max_x = rect.Left;
                    }
                }
            });

            if (cnc.IsCancellationRequested)
            {
                return(false);
            }

            lock (this)
            {
                if (double.IsNaN(max_x))
                {
                    PositionEof = Rect.Empty;
                }
                else
                {
                    PositionEof = new Rect(new Point(max_x, end_rect.Top), end_rect.Size);
                    PositionEof.Offset(rtb.HorizontalOffset, rtb.VerticalOffset);
                }
            }

            DelayedInvalidateVisual( );

            return(true);
        }
Beispiel #5
0
        bool CollectEols(ICancellable cnc, TextData td, Rect clip_rect, int top_index)
        {
            if (cnc.IsCancellationRequested)
            {
                return(false);
            }

            var rtb = Rtb;

            List <Rect> positions_eols = new List <Rect>( );

            // lines with no right-to-left segments

            var matches = EolRegex.Matches(td.Text);

            for (int i = 0; i < matches.Count; ++i)
            {
                if (cnc.IsCancellationRequested)
                {
                    return(false);
                }

                int index = matches[i].Index;

                if (index < top_index)
                {
                    continue;
                }

                int previous_index = i == 0 ? 0 : matches[i - 1].Index;

                bool has_RTL = false;

                for (int k = previous_index; k < index; ++k)
                {
                    if (cnc.IsCancellationRequested)
                    {
                        return(false);
                    }

                    if (UnicodeUtilities.IsRTL(td.Text[k]))
                    {
                        has_RTL = true;
                        break;
                    }
                }

                if (has_RTL)
                {
                    // RTL needs more navigation to find the rightmost X

                    Rect   left_rect = Rect.Empty;
                    double max_x     = double.NaN;

                    bool should_continue = false;
                    bool should_break    = false;

                    UITaskHelper.Invoke(rtb,
                                        () =>
                    {
                        TextPointer left = td.TextPointers.GetTextPointer(index);

                        left_rect = left.GetCharacterRect(LogicalDirection.Forward);

                        if (left_rect.Bottom < clip_rect.Top)
                        {
                            should_continue = true; return;
                        }
                        if (left_rect.Top > clip_rect.Bottom)
                        {
                            should_break = true; return;
                        }

                        max_x = left_rect.Left;

                        for (var tp = left.GetInsertionPosition(LogicalDirection.Backward); ;)
                        {
                            if (cnc.IsCancellationRequested)
                            {
                                return;
                            }

                            tp = tp.GetNextInsertionPosition(LogicalDirection.Backward);
                            if (tp == null)
                            {
                                break;
                            }

                            // WORKAROUND for lines like "0ראל", when "0" is matched and highlighted
                            tp = tp.GetInsertionPosition(LogicalDirection.Forward);

                            var rect_b = tp.GetCharacterRect(LogicalDirection.Backward);
                            var rect_f = tp.GetCharacterRect(LogicalDirection.Forward);

                            if (cnc.IsCancellationRequested)
                            {
                                return;
                            }

                            if (rect_b.Bottom < left_rect.Top && rect_f.Bottom < left_rect.Top)
                            {
                                break;
                            }

                            if (rect_b.Bottom > left_rect.Top)
                            {
                                if (max_x < rect_b.Left)
                                {
                                    max_x = rect_b.Left;
                                }
                            }

                            if (rect_f.Bottom > left_rect.Top)
                            {
                                if (max_x < rect_f.Left)
                                {
                                    max_x = rect_f.Left;
                                }
                            }
                        }
                    });

                    if (cnc.IsCancellationRequested)
                    {
                        return(false);
                    }
                    if (should_continue)
                    {
                        continue;
                    }
                    if (should_break)
                    {
                        break;
                    }

                    Rect eol_rect = new Rect(new Point(max_x, left_rect.Top), left_rect.Size);
                    eol_rect.Offset(rtb.HorizontalOffset, rtb.VerticalOffset);

                    positions_eols.Add(eol_rect);
                }
                else
                {
                    // no RTL; quick answer

                    Rect eol_rect = Rect.Empty;

                    UITaskHelper.Invoke(rtb,
                                        () =>
                    {
                        TextPointer left = td.TextPointers.GetTextPointer(index);

                        eol_rect = left.GetCharacterRect(LogicalDirection.Forward);
                    });

                    if (eol_rect.Bottom < clip_rect.Top)
                    {
                        continue;
                    }
                    if (eol_rect.Top > clip_rect.Bottom)
                    {
                        break;
                    }

                    eol_rect.Offset(rtb.HorizontalOffset, rtb.VerticalOffset);

                    positions_eols.Add(eol_rect);
                }
            }

            if (cnc.IsCancellationRequested)
            {
                return(false);
            }

            lock (this)
            {
                PositionsEols = positions_eols;
            }

            DelayedInvalidateVisual( );

            return(true);
        }