Version 1.1.0

- split of messages preserves item links, textures, substitutions and raid target markers
- added safety measures to prevent endless replacement loops
- bumped version for Shadowlands
- bumped version for Naxxramas
- split of messages with excessive length no longer causes errors or broken texts
- proper handling of umlauts
master
Lothar Buchholz 4 years ago
parent e53900d2b1
commit 475b2b3e1f

@ -0,0 +1,3 @@
## Interface: 90002
## X-Build: Retail

@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Version 1.1.0 - 2020-12-08
### Added
- split of messages preserves item links, textures, substitutions and raid target markers
- added safety measures to prevent endless replacement loops
### Changed
- bumped version for Shadowlands
- bumped version for Naxxramas
### Fixed
- split of messages with excessive length no longer causes errors or broken texts
- proper handling of umlauts
## Version 1.0.1 - 2020-10-17
### Changed
- bumped version for Shadowlands Pre-Patch
## Version 1.0.0 - 2020-09-01 [First Release] ## Version 1.0.0 - 2020-09-01 [First Release]
### Added ### Added
- info section with contact and thanks - info section with contact and thanks
@ -33,7 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- stop replacements per mapping - stop replacements per mapping
- more ooc recognition patterns - more ooc recognition patterns
### Fixed ### Fixed
- keep cases of over-long replacements - keep cases of replacements with excessive length
## Version 0.8.0-beta - 2020-06-14 [Feature Complete] ## Version 0.8.0-beta - 2020-06-14 [Feature Complete]
### Added ### Added

@ -1,9 +1,9 @@
## Interface: 11305 ## Interface: 11306
## Title: Grichelde ## Title: Grichelde
## Notes: Replaces characters of your chat input line before sending. ## Notes: Replaces characters of your chat input line before sending.
## Notes-de: Ersetzt eingegebene Zeichen in der Chat-Zeile vor dem Versand. ## Notes-de: Ersetzt eingegebene Zeichen in der Chat-Zeile vor dem Versenden.
## Version: 1.0.0 ## Version: 1.1.0
## Author: Teilzeit-Jedi ## Author: Teilzeit-Jedi
## eMail: tj@teilzeit-jedi.de ## eMail: tj@teilzeit-jedi.de

@ -2,44 +2,139 @@
local _G = _G local _G = _G
local Grichelde = _G.Grichelde or {} local Grichelde = _G.Grichelde or {}
local IsAddOnLoaded, assert, nilOrEmpty, pairs, ipairs, spairs, tContains, tFilter, tInsert, tConcat, tSize, tIsEmpty, find, sub, gsub, gmatch, getNextCharUtf8, isLetter, isUpper, isLower, toUpper, toLower, capitalize, trim, length, lengthUtf8 local IsAddOnLoaded, assert, nilOrEmpty, pairs, ipairs, spairs, tContains, tFilter, tInsert, tConcat, tSize, tIsEmpty, find, sub, gsub, gmatch, getNextCharUtf8, isLetter, isUpper, isLower, toUpper, toLower, capitalize, bytes2Char, trim, length, lengthUtf8
= Grichelde.F.IsAddOnLoaded, Grichelde.F.assert, Grichelde.F.nilOrEmpty, Grichelde.F.pairs, Grichelde.F.ipairs, Grichelde.F.spairs, Grichelde.F.tContains, Grichelde.F.tFilter, Grichelde.F.tInsert, Grichelde.F.tConcat, Grichelde.F.tSize, Grichelde.F.tIsEmpty, = Grichelde.F.IsAddOnLoaded, Grichelde.F.assert, Grichelde.F.nilOrEmpty, Grichelde.F.pairs, Grichelde.F.ipairs, Grichelde.F.spairs, Grichelde.F.tContains, Grichelde.F.tFilter, Grichelde.F.tInsert, Grichelde.F.tConcat, Grichelde.F.tSize, Grichelde.F.tIsEmpty,
Grichelde.F.find, Grichelde.F.sub, Grichelde.F.gsub, Grichelde.F.gmatch, Grichelde.F.getNextCharUtf8, Grichelde.F.isLetter, Grichelde.F.isUpper, Grichelde.F.isLower, Grichelde.F.toUpper, Grichelde.F.toLower, Grichelde.F.capitalize, Grichelde.F.trim, Grichelde.F.length, Grichelde.F.lengthUtf8 Grichelde.F.find, Grichelde.F.sub, Grichelde.F.gsub, Grichelde.F.gmatch, Grichelde.F.getNextCharUtf8, Grichelde.F.isLetter, Grichelde.F.isUpper, Grichelde.F.isLower, Grichelde.F.toUpper, Grichelde.F.toLower, Grichelde.F.capitalize, Grichelde.F.bytes2Char, Grichelde.F.trim, Grichelde.F.length, Grichelde.F.lengthUtf8
--- Splits a long text in longest possible chunks of <= 255 length, split at last available space --- Splits a long text in longest possible chunks of <= 255 length, split at last available space
-- @param text string -- @param text string
-- @return table -- @return array of chunks
function Grichelde:SplitText(text) function Grichelde:SplitText(text)
local chunks = {} local chunks = {}
local splitText = text local leftGuillemet = bytes2Char(194, 171) .. " "
local textSize = length(splitText or "") local rightGuillemet = " " .. bytes2Char(194, 187)
local chunkSize = Grichelde.INPUT_LIMIT - length(leftGuillemet) - length(rightGuillemet)
while (textSize > 255) do
local chunk = sub(splitText, 1, 255) local function preserveText(newText, chunk, blockText, posEnd)
local remaining = "" -- link found, block completed
self:TracePrint("SplitText : Found preservable text up to %s", posEnd)
-- special case: if space is the start of the next chunk, don't split this chunk local preserved = sub(newText, 1, posEnd)
if (sub(splitText, 256, 256) ~= ' ') then
-- split at last space, don't assign directly as nil might be returned if ((length(chunk) > 0) and (length(chunk .. blockText) > chunkSize)) then
local left, right = self:SplitOnLastMatch(chunk) -- block exceeds chunk, chunkify previous blocks
if (left ~= nil) then self:DebugPrint("SplitText : add chunk:", chunk)
chunk = left tInsert(chunks, chunk .. rightGuillemet)
end chunk = leftGuillemet .. trim(blockText)
if (right ~= nil) then else
remaining = right chunk = chunk .. blockText
end end
if ((length(chunk) > 0) and (length(chunk .. preserved) > chunkSize)) then
-- block exceeds chunk, chunkify previous blocks
self:DebugPrint("SplitText : add chunk:", chunk)
tInsert(chunks, chunk .. rightGuillemet)
chunk = leftGuillemet .. trim(preserved)
else
chunk = chunk .. preserved
end end
self:DebugPrint("SplitText : chunk:", chunk) blockText = ""
newText = sub(newText, posEnd + 1)
tInsert(chunks, chunk) return newText, chunk, blockText, posEnd
splitText = remaining .. sub(splitText, 256)
textSize = length(splitText)
end end
-- pickup remaining text < 255 if (length(text or "") <= Grichelde.INPUT_LIMIT) then
self:DebugPrint("SplitText : last chunk:", splitText) self:DebugPrint("SplitText : no chunk:", text)
tInsert(chunks, splitText) tInsert(chunks, text)
else
local lookAheads = { '|', '*', '<', '%', '{', '(', 'o' }
local newText = text or ""
local chunk, blockText = "", ""
local currentChar
local escape = 0
-- must not enforce UTF-8 support here, as the positions are used
while ((length(newText) > 0) and (escape < Grichelde.ENDLESS_LOOP_LIMIT)) do
escape = escape + 1
local previousChar = currentChar
local first, textAhead = getNextCharUtf8(newText)
currentChar = first
self:DebugPrint("SplitText : currentChar, escape: %s, %s", currentChar, escape)
self:TracePrint("SplitText : chunk:", chunk)
self:TracePrint("SplitText : newText:", newText)
-- as there is not OR in Luas pattern matching, search for all of the exclude patterns after another is
-- cumbersome and inefficient -> look for each char consecutively if it matches the starting pattern only
-- and if if matches do full pattern matching
if (currentChar == ' ') then
self:TracePrint("SplitText : block completed")
if ((length(chunk) > 0) and (length(chunk .. blockText) > chunkSize)) then
-- block exceeds chunk, chunkify previous blocks
self:DebugPrint("SplitText : add chunk:", chunk)
tInsert(chunks, chunk .. rightGuillemet)
chunk = leftGuillemet .. trim(blockText)
else
chunk = chunk .. blockText
end
blockText = currentChar
newText = textAhead
elseif (tContains(lookAheads, currentChar)) then
-- lookahead-check for all preservable patterns (itemLinks, textures, emotes, ooc, etc.)
-- link detection
local linkPosEnd = self:CheckForLink(newText, currentChar)
if (linkPosEnd ~= nil) then
-- link found, block completed
newText, chunk, blockText = preserveText(newText, chunk, blockText, linkPosEnd)
else
-- substitution detection
local substPosEnd = self:CheckForSubstitutions(newText, currentChar)
if (substPosEnd ~= nil) then
-- substitution found, block completed
newText, chunk, blockText = preserveText(newText, chunk, blockText, substPosEnd)
else
-- raid target marker detection
local rtmPosEnd = self:CheckForRaidTargetMarkers(newText, currentChar)
if (rtmPosEnd ~= nil) then
-- raid target marker found, block completed
newText, chunk, blockText = preserveText(newText, chunk, blockText, rtmPosEnd)
else
blockText = blockText .. currentChar
newText = textAhead
end
end
end
else
blockText = blockText .. currentChar
newText = textAhead
end
end
self:TracePrint("SplitText : main loop completed")
if (length(chunk .. blockText) > 0) then
-- catchup remaining text at the end
if (length(chunk .. blockText) > chunkSize) then
-- block exceeds chunk, chunkify previous blocks
if (length(chunk) > 0) then
self:DebugPrint("SplitText : add chunk:", chunk)
tInsert(chunks, chunk .. rightGuillemet)
chunk = leftGuillemet .. trim(blockText)
else
chunk = chunk .. blockText
end
else
chunk = chunk .. blockText
end
self:DebugPrint("SplitText : last chunk:", chunk)
-- sub(chunk, 1, 255) can result in broken UTF8 chars and error message
tInsert(chunks, chunk)
end
end
return chunks return chunks
end end
@ -63,10 +158,11 @@ function Grichelde:ReplaceCharacters(text, replName, replTable, consolidate, rep
local ciPattern = "" local ciPattern = ""
local ignored = {'^', '$', '(', ')', '.'} local ignored = {'^', '$', '(', ')', '.'}
local quantifiers = {'*', '+', '-', '?'} local quantifiers = {'*', '+', '-', '?'}
local pos = 1
local p, patRest = getNextCharUtf8(pattern) local p, patRest = getNextCharUtf8(pattern)
local escape = 0
while (p ~= nil) do while ((p ~= nil) and (escape < Grichelde.ENDLESS_LOOP_LIMIT)) do
escape = escape + 1
if (tContains(ignored, p) or tContains(quantifiers, p)) then if (tContains(ignored, p) or tContains(quantifiers, p)) then
-- ignore -- ignore
ciPattern = ciPattern .. p ciPattern = ciPattern .. p
@ -429,47 +525,43 @@ function Grichelde:ReplaceAndConsolidate(text, replacements)
return result return result
end end
--- Checks if the text starts with a preversable ignore pattern, such as itemLinks, textures, raid target icons, --- looks for colored items, item links or textures
--- emotes, ooc or %-substitutons and returns the end location of the match, or 0 if no pattern was found function Grichelde:CheckForLink(text, currentChar)
-- @param text string if (currentChar == "|") then
-- @param currentChar string(1) current character (first one) of the text, given for performance reasons
-- @param previousChar string(1) previous character of the text, otherwise unreachable
-- @param preserveEmotes boolean ignore replacements for emotes, for testing purposes
-- @return number
function Grichelde:CheckForPreversableText(text, currentChar, previousChar, replaceEmotes)
self:DebugPrint("CheckForPreversableText : text:", text)
local replaceEmotes = replaceEmotes or self.db.profile.channels.emote or false
-- Calling find on ever pattern might be inefficient but its way less code than marching over every character
if (currentChar == "|" ) then
for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.LINKS) do for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.LINKS) do
local pos1, pos2 = find(text, "^" .. pattern) local pos1, pos2 = find(text, "^" .. pattern)
if (pos1 == 1) and (pos2 ~= nil) then if (pos1 == 1) and (pos2 ~= nil) then
self:DebugPrint("CheckForPreversableText : Found link or texture pattern \"%s\" at (%d, %d)", pattern, pos1, pos2) local match = sub(text, pos1, pos2)
self:DebugPrint("CheckForLink : Found link or texture pattern \"%s\" at (%d, %d)", pattern, pos1, pos2)
return pos2 return pos2
end end
end end
end end
return nil
end
-- emote detection --- looks for emotes
function Grichelde:CheckForEmote(text, currentChar, replaceEmotes)
if (currentChar == "*" or currentChar == "<") then if (currentChar == "*" or currentChar == "<") then
for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.EMOTES) do for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.EMOTES) do
local pos1, pos2 = find(text, "^" .. pattern) local pos1, pos2 = find(text, "^" .. pattern)
if (pos1 == 1) and (pos2 ~= nil) then if (pos1 == 1) and (pos2 ~= nil) then
local emote = sub(text, pos1, pos2) local emote = sub(text, pos1, pos2)
if (not replaceEmotes) then if (not replaceEmotes) then
self:DebugPrint("CheckForPreversableText : Found emote \"%s\" at (%d, %d), but preserved it", emote, pos1, pos2) self:DebugPrint("CheckForEmote : Found emote \"%s\" at (%d, %d), but preserved it", emote, pos1, pos2)
return pos2 return pos2
else else
self:DebugPrint("CheckForPreversableText : ignoring emote \"%s\" at (%d, %d)", emote, pos1, pos2) self:DebugPrint("CheckForEmote : Processing emote \"%s\" at (%d, %d)", emote, pos1, pos2)
end end
end end
end end
end end
return nil
end
--- looks for %-substitutions
function Grichelde:CheckForSubstitutions(text, currentChar)
local lowerText = toLower(text) local lowerText = toLower(text)
-- %-substitutions
if (currentChar == "%") then if (currentChar == "%") then
for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.SUBSTITUTES) do for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.SUBSTITUTES) do
local pos1, pos2 = find(lowerText, "^" .. pattern) local pos1, pos2 = find(lowerText, "^" .. pattern)
@ -479,8 +571,12 @@ function Grichelde:CheckForPreversableText(text, currentChar, previousChar, repl
end end
end end
end end
return nil
end
-- raid target markers --- looks for general and localized raid target markers
function Grichelde:CheckForRaidTargetMarkers(text, currentChar)
local lowerText = toLower(text)
if (currentChar == "{") then if (currentChar == "{") then
-- rt1-9 -- rt1-9
local pattern = Grichelde.IGNORE_PATTERNS.RAID_TARGETS[1] local pattern = Grichelde.IGNORE_PATTERNS.RAID_TARGETS[1]
@ -501,8 +597,12 @@ function Grichelde:CheckForPreversableText(text, currentChar, previousChar, repl
end end
end end
end end
return nil
end
-- ooc bracket detection --- looks for ooc with brackets
function Grichelde:CheckForOocBrackets(text, currentChar)
local lowerText = toLower(text)
if (currentChar == "(") then if (currentChar == "(") then
for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.OOC_BRACKETS) do for _, pattern in ipairs(Grichelde.IGNORE_PATTERNS.OOC_BRACKETS) do
local pos1, pos2 = find(lowerText, "^" .. pattern) local pos1, pos2 = find(lowerText, "^" .. pattern)
@ -512,15 +612,63 @@ function Grichelde:CheckForPreversableText(text, currentChar, previousChar, repl
end end
end end
end end
return nil
end
-- ooc without brackets: remaing text is treated as ooc completely! --- looks for ooc without brackets
function Grichelde:CheckForOocNoBrackets(text, currentChar, previousChar)
local lowerText = toLower(text)
if (currentChar == "o") then if (currentChar == "o") then
local pattern = Grichelde.IGNORE_PATTERNS.OOC_NO_BRACKETS[1] local pattern = Grichelde.IGNORE_PATTERNS.OOC_NO_BRACKETS[1]
if ((previousChar == nil) or (find(previousChar, "%s") ~= nil)) and (find(lowerText, pattern) ~= nil) then if ((previousChar == nil) or (find(previousChar, "%s") ~= nil)) and (find(lowerText, pattern) ~= nil) then
self:DebugPrint("CheckForPreversableText : ooc for remaing text") self:DebugPrint("CheckForPreversableText : ooc for remaing text")
-- remaing text is treated as ooc completely!
return length(text) return length(text)
end end
end end
return nil
end
--- Checks if the text starts with a preversable ignore pattern, such as itemLinks, textures, raid target icons,
--- emotes, ooc or %-substitutons and returns the end location of the match, or 0 if no pattern was found
-- @param text string
-- @param currentChar string(1) current character (first one) of the text, given for performance reasons
-- @param previousChar string(1) previous character of the text, otherwise unreachable
-- @param preserveEmotes boolean ignore replacements for emotes, for testing purposes
-- @return number
function Grichelde:CheckForPreversableText(text, currentChar, previousChar, replaceEmotes)
self:DebugPrint("CheckForPreversableText : text:", text)
local replaceEmotes = replaceEmotes or self.db.profile.channels.emote or false
local linkPos = self:CheckForLink(text, currentChar)
if (linkPos ~= nil) then
return linkPos
end
local emotePos = self:CheckForEmote(text, currentChar, replaceEmotes)
if (emotePos ~= nil) then
return emotePos
end
local substPos = self:CheckForSubstitutions(text, currentChar)
if (substPos ~= nil) then
return substPos
end
local rtmPos = self:CheckForRaidTargetMarkers(text, currentChar)
if (rtmPos ~= nil) then
return rtmPos
end
local oocBracketPos = self:CheckForOocBrackets(text, currentChar)
if (oocBracketPos ~= nil) then
return oocBracketPos
end
local oocNoBracketPos = self:CheckForOocNoBrackets(text, currentChar, previousChar)
if (oocNoBracketPos ~= nil) then
return oocNoBracketPos
end
self:DebugPrint("CheckForPreversableText : no ignore pattern found") self:DebugPrint("CheckForPreversableText : no ignore pattern found")
return 0 return 0
@ -536,49 +684,49 @@ function Grichelde:ReplaceText(text, replacements, replaceEmotes)
local newText = text local newText = text
local preserveEmotes = replaceEmotes or self.db.profile.channels.emote or false local preserveEmotes = replaceEmotes or self.db.profile.channels.emote or false
local replacements = replacements or self.db.profile.replacements or {} local replacements = replacements or self.db.profile.replacements or {}
local finalText = "" local finalText, replaceText = "", ""
local currentChar
local currentChar, previousChar local escape = 0
local current = 1
local lastStart = 1 -- must not enforce UTF-8 support here, as the positions are used
while ((length(newText) > 0) and (escape < Grichelde.ENDLESS_LOOP_LIMIT)) do
-- no UTF-8 support required here, as the positions are used escape = escape + 1
while current <= length(newText) do local previousChar = currentChar
previousChar = currentChar local first, textAhead = getNextCharUtf8(newText)
currentChar = sub(newText, current, current) currentChar = first
self:TracePrint("ReplaceText : current/char : %s,%s", current, currentChar) self:TracePrint("ReplaceText : currentChar : %s", currentChar)
-- as there is not OR in Luas pattern matching, search for all of the exclude patterns after another is -- as there is not OR in Luas pattern matching, search for all of the exclude patterns after another is
-- cumbersome and inefficient -> look for each char consecutively if it matches the starting pattern only -- cumbersome and inefficient -> look for each char consecutively if it matches the starting pattern only
-- and if if matches do full pattern matching -- and if if matches do full pattern matching
if (not tContains(lookAheads, currentChar)) then if (tContains(lookAheads, currentChar)) then
current = current + 1
else
-- lookahead-check for all preservable patterns (itemLinks, textures, emotes, ooc, etc.) -- lookahead-check for all preservable patterns (itemLinks, textures, emotes, ooc, etc.)
local textAhead = sub(newText, current) --local textAhead = sub(newText, current)
local posEnd = self:CheckForPreversableText(textAhead, currentChar, previousChar, preserveEmotes) local posEnd = self:CheckForPreversableText(newText, currentChar, previousChar, preserveEmotes)
if (posEnd > 0) then if (posEnd > 0) then
self:DebugPrint("ReplaceText : Found an ignore pattern") self:DebugPrint("ReplaceText : Found an ignore pattern")
-- split text and continue after preserved text -- replace all text up until now
local textBefore = sub(newText, lastStart, current - 1) local replacement = self:ReplaceAndConsolidate(replaceText, replacements)
local replacement = self:ReplaceAndConsolidate(textBefore, replacements) local preserved = sub(newText, 1, posEnd)
local preservedText = sub(textAhead, 1, posEnd)
finalText = finalText .. replacement .. preservedText finalText = finalText .. replacement .. preserved
current = current + posEnd replaceText = ""
lastStart = current newText = sub(newText, posEnd + 1)
self:DebugPrint("ReplaceText : restarting at", lastStart) self:DebugPrint("ReplaceText : remaining text", newText)
else else
-- no corresponding end was found to start pattern, continue loop with next char -- no corresponding end was found to start pattern, continue loop with next char
current = current + 1 replaceText = replaceText .. currentChar
newText = textAhead
end end
else
replaceText = replaceText .. currentChar
newText = textAhead
end end
end end
-- catchup remaining text to the end -- catchup remaining text to the end
local remainingText = sub(newText, lastStart) local replacement = self:ReplaceAndConsolidate(replaceText, replacements)
local replacement = self:ReplaceAndConsolidate(remainingText, replacements)
finalText = finalText .. replacement finalText = finalText .. replacement
self:DebugPrint("ReplaceText : replaced \"%s\"", text) self:DebugPrint("ReplaceText : replaced \"%s\"", text)
@ -592,22 +740,24 @@ function Grichelde:IsOneBigEmote(text)
-- emote detection -- emote detection
local isEmote = false local isEmote = false
-- scheme *emote* local firstChar, rest = getNextCharUtf8(firstWord)
if (sub(firstWord, 1, 1) == "<") then
-- scheme <emote>
if (firstChar == "<") then
-- search for emote end -- search for emote end
local _, emoteEnd = find(text, "%>", 2) local _, emoteEnd = find(text, "%>", 2)
isEmote = (emoteEnd == length(text)) isEmote = (emoteEnd == lengthUtf8(text))
end end
if (not isEmote and (sub(firstWord, 1, 1) == "*")) then if (not isEmote and (firstChar == "*")) then
-- search for emote end if (getNextCharUtf8(rest) == "*") then
local _, emoteEnd = find(text, "%*", 2) -- scheme **emote**
isEmote = (emoteEnd == length(text)) local _, emoteEnd = find(text, "%*%*", 3)
end isEmote = (emoteEnd == lengthUtf8(text))
-- scheme **emote** else
if (not isEmote and (sub(firstWord, 1, 2) == "**")) then -- scheme *emote*
-- search for emote end local _, emoteEnd = find(text, "%*", 2)
local _, emoteEnd = find(text, "%*%*", 3) isEmote = (emoteEnd == lengthUtf8(text))
isEmote = (emoteEnd == length(text)) end
end end
-- the whole text is one big emote -- the whole text is one big emote
@ -659,7 +809,7 @@ function Grichelde:CheckReplacementAllowed(text, channel)
assert(firstWord ~= nil, "firstWord is never nil") assert(firstWord ~= nil, "firstWord is never nil")
-- don't replace slash commands -- don't replace slash commands
if (sub(firstWord, 1, 1) == "/") then if (getNextCharUtf8(firstWord) == "/") then
self:DebugPrint("CheckReplacementAllowed : skip other slash commands:", firstWord) self:DebugPrint("CheckReplacementAllowed : skip other slash commands:", firstWord)
return false return false
end end
@ -691,7 +841,7 @@ function Grichelde:CheckAndExtractMessageTypeTarget(message)
end end
-- first word should be a chat command -- first word should be a chat command
if (sub(message, 1, 1) == "/") then if (getNextCharUtf8(message) == "/") then
-- extract chat command -- extract chat command
local chatCmd, targetAndText = self:SplitOnFirstMatch(message) local chatCmd, targetAndText = self:SplitOnFirstMatch(message)
assert(chatCmd ~= nil, "chatCmd is never nil") assert(chatCmd ~= nil, "chatCmd is never nil")

@ -5,6 +5,8 @@ local Grichelde = _G.Grichelde or {}
-- constants and upvalues -- constants and upvalues
Grichelde.LOG_LEVEL = { DEBUG = 1, TRACE = 2 } Grichelde.LOG_LEVEL = { DEBUG = 1, TRACE = 2 }
Grichelde.INPUT_LIMIT = 255
Grichelde.ENDLESS_LOOP_LIMIT = 10000
Grichelde.MAPPING_OFFSET = 10 Grichelde.MAPPING_OFFSET = 10
Grichelde.MINIMAP_ENABLED = 1.0 Grichelde.MINIMAP_ENABLED = 1.0
Grichelde.MINIMAP_DARKENDED = 0.5 Grichelde.MINIMAP_DARKENDED = 0.5
@ -116,6 +118,7 @@ Grichelde.BLIZZ_TYPE_TO_OPTIONS = {
} }
-- do not replace these patterns -- do not replace these patterns
-- combined item links in the chat will look like this: |cff9d9d9d|Hitem:3299::::::::20:257::::::|h[Fractured Canine]|h|r
Grichelde.IGNORE_PATTERNS = { Grichelde.IGNORE_PATTERNS = {
LINKS = { LINKS = {
"|[Cc]%x%x%x%x%x%x%x%x.-|r", -- colored items (or links) "|[Cc]%x%x%x%x%x%x%x%x.-|r", -- colored items (or links)

Loading…
Cancel
Save