- switching to new C_AddOns API changes
- cascaded message hooking for Retail v12 engine - messages during encounters are sent unchanged, with a one-time notice - ignore numbered chats that do not exist - /r no longer sends to an empty whisper target if the last told target is unavailable - fixed replacements in instance chats - messages to unknown numbered channels are now discarded - right-click on the minimap button
This commit is contained in:
+3
-1
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Fixed
|
### Fixed
|
||||||
- handling of german umlauts (and other unicode characters)
|
- handling of german umlauts (and other unicode characters)
|
||||||
- updated libraries and bumped version for all incarnations of WoW (Classic Era, Forever, Classic, Retail)
|
- updated libraries and bumped version for all incarnations of WoW (Classic Era, Forever, Classic, Retail)
|
||||||
-
|
- adaptations to Retail v12 new Chat handling (Send API, encounter lockdown, instance chat)
|
||||||
|
- /r no longer sends to an empty whisper target if the last told target is unavailable
|
||||||
|
|
||||||
## Version 1.1.6 - 2023-01-18
|
## Version 1.1.6 - 2023-01-18
|
||||||
### Changed
|
### Changed
|
||||||
- bumped version for latest WotLK Classic patch
|
- bumped version for latest WotLK Classic patch
|
||||||
|
|||||||
+4
-2
@@ -20,6 +20,7 @@ local _G = _G
|
|||||||
|
|
||||||
-- initialize addon
|
-- initialize addon
|
||||||
local Grichelde = LibStub("AceAddon-3.0"):NewAddon(AddonTable, AddonName, "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0")
|
local Grichelde = LibStub("AceAddon-3.0"):NewAddon(AddonTable, AddonName, "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0")
|
||||||
|
local GetAddOnMetadata = (_G.C_AddOns and _G.C_AddOns.GetAddOnMetadata) or _G.GetAddOnMetadata
|
||||||
Grichelde.version = GetAddOnMetadata(AddonName, "Version")
|
Grichelde.version = GetAddOnMetadata(AddonName, "Version")
|
||||||
Grichelde.build = GetAddOnMetadata(AddonName, "X-Build") or "Development"
|
Grichelde.build = GetAddOnMetadata(AddonName, "X-Build") or "Development"
|
||||||
--Grichelde.era = _G.WOW_PROJECT_ID == _G.WOW_PROJECT_CLASSIC
|
--Grichelde.era = _G.WOW_PROJECT_ID == _G.WOW_PROJECT_CLASSIC
|
||||||
@@ -40,7 +41,7 @@ end
|
|||||||
|
|
||||||
function Grichelde:OnEnable()
|
function Grichelde:OnEnable()
|
||||||
-- Hook in before message is sent to replace all character occurrences where replacements have been defined in the options
|
-- Hook in before message is sent to replace all character occurrences where replacements have been defined in the options
|
||||||
self:RawHook("SendChatMessage", true)
|
self:HookSendChatMessage()
|
||||||
|
|
||||||
self.options, self.dialog = self:SetupOptions()
|
self.options, self.dialog = self:SetupOptions()
|
||||||
self.ldb, self.icon = self:MinimapButton()
|
self.ldb, self.icon = self:MinimapButton()
|
||||||
@@ -56,7 +57,8 @@ function Grichelde:OnEnable()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Grichelde:OnDisable()
|
function Grichelde:OnDisable()
|
||||||
self:Unhook("SendChatMessage")
|
self:UnhookAll()
|
||||||
|
self.originalSend = nil
|
||||||
self:CloseOptions()
|
self:CloseOptions()
|
||||||
self:HideMinimapButton()
|
self:HideMinimapButton()
|
||||||
self:UnregisterChatCommand("grichelde")
|
self:UnregisterChatCommand("grichelde")
|
||||||
|
|||||||
+86
-9
@@ -2,8 +2,8 @@
|
|||||||
local _G = _G or getfenv()
|
local _G = _G or getfenv()
|
||||||
local Grichelde = _G.Grichelde or {}
|
local Grichelde = _G.Grichelde or {}
|
||||||
|
|
||||||
local IsAddOnLoaded, assert, nilOrEmpty, pairs, ipairs, spairs, tContains, tFilter, tInsert, tIsEmpty, tSize, find, sub, gsub, getNextCharUtf8, isUtf8MultiByte, getUtf8Sequence, isUpper, isLower, toUpper, toLower, bytes2Char, trim, length, lengthUtf8
|
local assert, nilOrEmpty, pairs, ipairs, spairs, tContains, tFilter, tInsert, tIsEmpty, tSize, find, sub, gsub, getNextCharUtf8, isUtf8MultiByte, getUtf8Sequence, isUpper, isLower, toUpper, toLower, 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.tIsEmpty, Grichelde.F.tSize,
|
= 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.tIsEmpty, Grichelde.F.tSize,
|
||||||
Grichelde.F.find, Grichelde.F.sub, Grichelde.F.gsub, Grichelde.F.getNextCharUtf8, Grichelde.F.isUtf8MultiByte, Grichelde.F.getUtf8Sequence, Grichelde.F.isUpper, Grichelde.F.isLower, Grichelde.F.toUpper, Grichelde.F.toLower, Grichelde.F.bytes2Char, Grichelde.F.trim, Grichelde.F.length, Grichelde.F.lengthUtf8
|
Grichelde.F.find, Grichelde.F.sub, Grichelde.F.gsub, Grichelde.F.getNextCharUtf8, Grichelde.F.isUtf8MultiByte, Grichelde.F.getUtf8Sequence, Grichelde.F.isUpper, Grichelde.F.isLower, Grichelde.F.toUpper, Grichelde.F.toLower, 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
|
||||||
@@ -145,10 +145,10 @@ function Grichelde:SendChunkifiedChatMessage(message, ...)
|
|||||||
self:DebugPrint("SendChunkifiedChatMessage : #chunks:", tSize(chunks))
|
self:DebugPrint("SendChunkifiedChatMessage : #chunks:", tSize(chunks))
|
||||||
|
|
||||||
for _, chunk in ipairs(chunks) do
|
for _, chunk in ipairs(chunks) do
|
||||||
self.hooks["SendChatMessage"](chunk, ...);
|
self:SendOriginal(chunk, ...)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.hooks["SendChatMessage"](message, ...);
|
self:SendOriginal(message, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -886,8 +886,18 @@ function Grichelde:CheckAndExtractMessageTypeTarget(message)
|
|||||||
-- special reply handling
|
-- special reply handling
|
||||||
if ("/r" == chatCmd) or ("/reply" == chatCmd) then
|
if ("/r" == chatCmd) or ("/reply" == chatCmd) then
|
||||||
-- reuse last type and target if possible
|
-- reuse last type and target if possible
|
||||||
local lastTold, lastToldType = ChatEdit_GetLastToldTarget()
|
-- TODO: add the Retail 12.x replacement of ChatEdit_GetLastToldTarget once confirmed in-game
|
||||||
|
local lastTold, lastToldType
|
||||||
|
if (_G.ChatEdit_GetLastToldTarget ~= nil) then
|
||||||
|
lastTold, lastToldType = _G.ChatEdit_GetLastToldTarget()
|
||||||
|
end
|
||||||
self:DebugPrint("CheckAndExtractMessageTypeTarget : lastTell, lastTellType =", lastTold, lastToldType)
|
self:DebugPrint("CheckAndExtractMessageTypeTarget : lastTell, lastTellType =", lastTold, lastToldType)
|
||||||
|
|
||||||
|
if (nilOrEmpty(lastTold)) then
|
||||||
|
self:ErrorPrint(self.L.Error_InvalidWhisperTarget)
|
||||||
|
-- dont send text at all
|
||||||
|
return nil
|
||||||
|
end
|
||||||
return targetAndText, lastToldType or "WHISPER", lastTold
|
return targetAndText, lastToldType or "WHISPER", lastTold
|
||||||
elseif ("/tt" == chatCmd) then
|
elseif ("/tt" == chatCmd) then
|
||||||
-- determine target from game world selection
|
-- determine target from game world selection
|
||||||
@@ -931,7 +941,7 @@ function Grichelde:CheckAndExtractMessageTypeTarget(message)
|
|||||||
local _, _, channelNumber = find(chatCmd, "^/(%d+)")
|
local _, _, channelNumber = find(chatCmd, "^/(%d+)")
|
||||||
if (channelNumber ~= nil) then
|
if (channelNumber ~= nil) then
|
||||||
local channelId = GetChannelName(channelNumber)
|
local channelId = GetChannelName(channelNumber)
|
||||||
if (channelId ~= nil) then
|
if (channelId ~= nil) and (channelId > 0) then
|
||||||
return targetAndText, "CHANNEL", channelId
|
return targetAndText, "CHANNEL", channelId
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -950,8 +960,50 @@ function Grichelde:CheckAndExtractMessageTypeTarget(message)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Hooks C_ChatInfo.SendChatMessage (Retail) and the global SendChatMessage (Classic, deprecated alias on Retail).
|
||||||
|
--- The original C_ChatInfo function is preferred for sending.
|
||||||
|
function Grichelde:HookSendChatMessage()
|
||||||
|
local chatInfo = _G.C_ChatInfo
|
||||||
|
if (chatInfo ~= nil) and (chatInfo.SendChatMessage ~= nil) then
|
||||||
|
self:RawHook(chatInfo, "SendChatMessage", "SendChatMessage", true)
|
||||||
|
self.originalSend = self.hooks[chatInfo]["SendChatMessage"]
|
||||||
|
end
|
||||||
|
|
||||||
|
if (_G.SendChatMessage ~= nil) then
|
||||||
|
self:RawHook("SendChatMessage", true)
|
||||||
|
self.originalSend = self.originalSend or self.hooks["SendChatMessage"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a message with the original (unhooked) send function.
|
||||||
|
function Grichelde:SendOriginal(...)
|
||||||
|
return self.originalSend(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Midnight blocks chat modifications by addons during instance encounters.
|
||||||
|
--- Prints a notice once per lockdown.
|
||||||
|
-- @return boolean
|
||||||
|
function Grichelde:IsChatLockedDown()
|
||||||
|
local chatInfo = _G.C_ChatInfo
|
||||||
|
if (chatInfo == nil) or (chatInfo.InChatMessagingLockdown == nil) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if (chatInfo.InChatMessagingLockdown()) then
|
||||||
|
if (not self.lockdownNoticeShown) then
|
||||||
|
self.lockdownNoticeShown = true
|
||||||
|
self:PrefixedPrint(self.L.Chat_Lockdown_Notice)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
self.lockdownNoticeShown = false
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
function Grichelde:CleanseMessage(message)
|
function Grichelde:CleanseMessage(message)
|
||||||
local text = message or ""
|
local text = message or ""
|
||||||
|
local IsAddOnLoaded = (_G.C_AddOns and _G.C_AddOns.IsAddOnLoaded) or _G.IsAddOnLoaded
|
||||||
if (IsAddOnLoaded("Misspelled")) then
|
if (IsAddOnLoaded("Misspelled")) then
|
||||||
self:DebugPrint("Misspelled detected: cleansing message")
|
self:DebugPrint("Misspelled detected: cleansing message")
|
||||||
text = _G.Misspelled:RemoveHighlighting(message)
|
text = _G.Misspelled:RemoveHighlighting(message)
|
||||||
@@ -971,7 +1023,12 @@ function Grichelde:SendChatMessageOverride(message, ...)
|
|||||||
local msg, type, chan = self:CheckAndExtractMessageTypeTarget(cleasendText)
|
local msg, type, chan = self:CheckAndExtractMessageTypeTarget(cleasendText)
|
||||||
|
|
||||||
if (msg ~= nil) then
|
if (msg ~= nil) then
|
||||||
|
if (not self:IsChatLockedDown()) then
|
||||||
msg = self:ReplaceText(msg)
|
msg = self:ReplaceText(msg)
|
||||||
|
else
|
||||||
|
-- do not modify message in any way during encounters
|
||||||
|
-- msg = msg .. self.L.Chat_Lockdown_Suffix
|
||||||
|
end
|
||||||
|
|
||||||
if (type ~= nil) then
|
if (type ~= nil) then
|
||||||
self:SendChunkifiedChatMessage(msg, type, fallbackLang, chan, ...)
|
self:SendChunkifiedChatMessage(msg, type, fallbackLang, chan, ...)
|
||||||
@@ -989,19 +1046,39 @@ end
|
|||||||
-- @param language string
|
-- @param language string
|
||||||
-- @param channel string
|
-- @param channel string
|
||||||
function Grichelde:SendChatMessage(message, type, ...)
|
function Grichelde:SendChatMessage(message, type, ...)
|
||||||
|
if (self.isReplacing) then
|
||||||
|
-- re-entered through the other hooked send function, text is already replaced
|
||||||
|
self:DebugPrint("SendChatMessage : already replacing")
|
||||||
|
self:SendOriginal(message, type, ...)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.isReplacing = true
|
||||||
|
-- always reset the guard, even if replacing fails
|
||||||
|
local ok, err = pcall(self.ReplaceAndSendChatMessage, self, message, type, ...)
|
||||||
|
self.isReplacing = false
|
||||||
|
if (not ok) then
|
||||||
|
error(err, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Grichelde:ReplaceAndSendChatMessage(message, type, ...)
|
||||||
if (not self.db.profile.enabled) then
|
if (not self.db.profile.enabled) then
|
||||||
self:DebugPrint("SendChatMessage : disabled")
|
self:DebugPrint("SendChatMessage : disabled")
|
||||||
self.hooks["SendChatMessage"](message, type, ...);
|
self:SendOriginal(message, type, ...)
|
||||||
elseif (nilOrEmpty(message)) then
|
elseif (nilOrEmpty(message)) then
|
||||||
self:DebugPrint("SendChatMessage : no text")
|
self:DebugPrint("SendChatMessage : no text")
|
||||||
self.hooks["SendChatMessage"](message, type, ...);
|
self:SendOriginal(message, type, ...)
|
||||||
|
elseif (self:IsChatLockedDown()) then
|
||||||
|
self:DebugPrint("SendChatMessage : chat lockdown")
|
||||||
|
self:SendOriginal(message, type, ...)
|
||||||
else
|
else
|
||||||
local cleasendText = self:CleanseMessage(message)
|
local cleasendText = self:CleanseMessage(message)
|
||||||
if (self:CheckReplacementAllowed(cleasendText, type)) then
|
if (self:CheckReplacementAllowed(cleasendText, type)) then
|
||||||
cleasendText = self:ReplaceText(cleasendText)
|
cleasendText = self:ReplaceText(cleasendText)
|
||||||
self:SendChunkifiedChatMessage(cleasendText, type, ...)
|
self:SendChunkifiedChatMessage(cleasendText, type, ...)
|
||||||
else
|
else
|
||||||
self.hooks["SendChatMessage"](message, type, ...);
|
self:SendOriginal(message, type, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -114,7 +114,7 @@ Grichelde.BLIZZ_TYPE_TO_OPTIONS = {
|
|||||||
["OFFICER"] = "officer",
|
["OFFICER"] = "officer",
|
||||||
["RAID"] = "raid",
|
["RAID"] = "raid",
|
||||||
["RAID_WARNING"] = "raidWarning",
|
["RAID_WARNING"] = "raidWarning",
|
||||||
["INSTANCE"] = "instance",
|
["INSTANCE_CHAT"] = "instance",
|
||||||
["BATTLEGROUND"] = "battleground",
|
["BATTLEGROUND"] = "battleground",
|
||||||
["WHISPER"] = "whisper",
|
["WHISPER"] = "whisper",
|
||||||
}
|
}
|
||||||
@@ -486,7 +486,6 @@ end
|
|||||||
|
|
||||||
-- faster function lookups by mapping to local refs
|
-- faster function lookups by mapping to local refs
|
||||||
Grichelde.F = {
|
Grichelde.F = {
|
||||||
IsAddOnLoaded = _G.IsAddOnLoaded,
|
|
||||||
assert = _G.assert,
|
assert = _G.assert,
|
||||||
type = _G.type,
|
type = _G.type,
|
||||||
print = _G.print,
|
print = _G.print,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ function Grichelde:MinimapButton()
|
|||||||
icon = "Interface\\Icons\\Spell_Holy_Silence",
|
icon = "Interface\\Icons\\Spell_Holy_Silence",
|
||||||
--icon = ([[Interface\Addons\%s\%s]]):format(self.name, self.name),
|
--icon = ([[Interface\Addons\%s\%s]]):format(self.name, self.name),
|
||||||
OnClick = clickHandler,
|
OnClick = clickHandler,
|
||||||
OnRightClick = function() self:ShowMappings() end,
|
OnRightClick = function() self:ToogleMappings() end,
|
||||||
OnTooltipShow = updateTooltip,
|
OnTooltipShow = updateTooltip,
|
||||||
iconR = darkened,
|
iconR = darkened,
|
||||||
iconG = darkened,
|
iconG = darkened,
|
||||||
|
|||||||
@@ -415,9 +415,7 @@ function Grichelde:SetupOptions()
|
|||||||
-- Adding options to blizzard frame
|
-- Adding options to blizzard frame
|
||||||
LibStub("AceConfig-3.0"):RegisterOptionsTable(self.name, options)
|
LibStub("AceConfig-3.0"):RegisterOptionsTable(self.name, options)
|
||||||
local dialog = LibStub("AceConfigDialog-3.0")
|
local dialog = LibStub("AceConfigDialog-3.0")
|
||||||
local _, categoryID = dialog:AddToBlizOptions(self.name, self.L.AddonName)
|
dialog:AddToBlizOptions(self.name, self.L.AddonName)
|
||||||
|
|
||||||
self.optionsCategoryID = categoryID
|
|
||||||
return options, dialog
|
return options, dialog
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -466,8 +464,9 @@ function Grichelde:RefreshProfiles(event, _, profileName)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Grichelde:ToggleOptions()
|
function Grichelde:ToggleOptions()
|
||||||
self:DebugPrint("ToggleOptions : options open: ", not not self.dialog.OpenFrames[self.name])
|
local isOpen = (self.dialog ~= nil) and (self.dialog.OpenFrames[self.name] ~= nil)
|
||||||
if (self.dialog ~= nil) and (self.dialog.OpenFrames[self.name] ~= nil) then
|
self:DebugPrint("ToggleOptions : options open: ", isOpen)
|
||||||
|
if (isOpen) then
|
||||||
self:CloseOptions()
|
self:CloseOptions()
|
||||||
else
|
else
|
||||||
self:OpenOptions()
|
self:OpenOptions()
|
||||||
|
|||||||
+3
-3
@@ -171,7 +171,7 @@ end
|
|||||||
--- Print UI options to chat frame
|
--- Print UI options to chat frame
|
||||||
function Grichelde:PrintOptions()
|
function Grichelde:PrintOptions()
|
||||||
self:PrefixedPrint(cPrefix(self.L.Debug_Options))
|
self:PrefixedPrint(cPrefix(self.L.Debug_Options))
|
||||||
self:LogPrint(-1, function(...)
|
self:LogPrint(function(...)
|
||||||
print(cPrefix(self.L.AddonName) .. ":", self:Format(...))
|
print(cPrefix(self.L.AddonName) .. ":", self:Format(...))
|
||||||
end, self.options.args.replacements.args)
|
end, self.options.args.replacements.args)
|
||||||
end
|
end
|
||||||
@@ -179,7 +179,7 @@ end
|
|||||||
--- Print current DB profile
|
--- Print current DB profile
|
||||||
function Grichelde:PrintProfile()
|
function Grichelde:PrintProfile()
|
||||||
self:PrefixedPrint(cPrefix(self.L.Debug_Profile))
|
self:PrefixedPrint(cPrefix(self.L.Debug_Profile))
|
||||||
self:LogPrint(-1, function(...)
|
self:LogPrint(function(...)
|
||||||
print(cPrefix(self.L.AddonName) .. ":", self:Format(...))
|
print(cPrefix(self.L.AddonName) .. ":", self:Format(...))
|
||||||
end, self.db.profile)
|
end, self.db.profile)
|
||||||
end
|
end
|
||||||
@@ -187,7 +187,7 @@ end
|
|||||||
--- Print DB replacements to chat frame
|
--- Print DB replacements to chat frame
|
||||||
function Grichelde:PrintMappings()
|
function Grichelde:PrintMappings()
|
||||||
self:PrefixedPrint(cPrefix(self.L.Debug_Mappings))
|
self:PrefixedPrint(cPrefix(self.L.Debug_Mappings))
|
||||||
self:LogPrint(-1, function(...)
|
self:LogPrint(function(...)
|
||||||
print(cPrefix(self.L.AddonName) .. ":", self:Format(...))
|
print(cPrefix(self.L.AddonName) .. ":", self:Format(...))
|
||||||
end, self.db.profile.replacements)
|
end, self.db.profile.replacements)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ L.Error_InvalidCommand = "Ung\195\188ltiger Befehl"
|
|||||||
L.Error_InvalidChannel = "Ung\195\188ltiger Kanal"
|
L.Error_InvalidChannel = "Ung\195\188ltiger Kanal"
|
||||||
L.Error_InvalidWhisperTarget = "Ung\195\188ltiger Fl\195\188sterziel"
|
L.Error_InvalidWhisperTarget = "Ung\195\188ltiger Fl\195\188sterziel"
|
||||||
L.Error_UnsupportedChannel = "Nicht unterst\195\188tzter Kanal"
|
L.Error_UnsupportedChannel = "Nicht unterst\195\188tzter Kanal"
|
||||||
|
L.Chat_Lockdown_Notice = "Der Chat ist w\195\164hrend dieses Kampfes durch das Spiel gesperrt, Grichelde hält sich zurück."
|
||||||
|
L.Chat_Lockdown_Suffix = "(ignoriert von Grichelde)"
|
||||||
|
|
||||||
-- profiles
|
-- profiles
|
||||||
L.Profiles_Available = "Verf\195\188gbare Profile:"
|
L.Profiles_Available = "Verf\195\188gbare Profile:"
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ L.Error_InvalidCommand = "Invalid command"
|
|||||||
L.Error_InvalidChannel = "Invalid channel"
|
L.Error_InvalidChannel = "Invalid channel"
|
||||||
L.Error_InvalidWhisperTarget = "Invalid whisper target"
|
L.Error_InvalidWhisperTarget = "Invalid whisper target"
|
||||||
L.Error_UnsupportedChannel = "Unsupported channel"
|
L.Error_UnsupportedChannel = "Unsupported channel"
|
||||||
|
L.Chat_Lockdown_Notice = "Chat is locked by the game during this encounter. Grichelde will remain passive."
|
||||||
|
L.Chat_Lockdown_Suffix = "(ignored by Grichelde)"
|
||||||
|
|
||||||
-- profiles
|
-- profiles
|
||||||
L.Profiles_Available = "Available profiles:"
|
L.Profiles_Available = "Available profiles:"
|
||||||
|
|||||||
Reference in New Issue
Block a user