diff --git a/ElvUI_SLE/defaults/profile.lua b/ElvUI_SLE/defaults/profile.lua index e615f20..93e1a94 100644 --- a/ElvUI_SLE/defaults/profile.lua +++ b/ElvUI_SLE/defaults/profile.lua @@ -113,6 +113,12 @@ P["sle"] = { ["style"] = "DEFAULT", ["color"] = {r = 1, g = 1, b = 1}, }, + ["invite"] = { + ["altInv"] = false, + ["invLinks"] = false, + ["keys"] = "invite", + ["color"] = {r = 1, g = 1, b = 0}, + }, }, --Datbars ["databars"] = { diff --git a/ElvUI_SLE/locales/english.lua b/ElvUI_SLE/locales/english.lua index ffc2e4b..e266074 100644 --- a/ElvUI_SLE/locales/english.lua +++ b/ElvUI_SLE/locales/english.lua @@ -279,6 +279,12 @@ L["Shows you which of docked chat tabs is currently selected."] = true L["Chat history size"] = true L["Sets how many messages will be stored in history."] = true L["Following options determine which channels to save in chat history.\nNote: disabling a channel will immideately delete saved info for that channel."] = true +L["Alt-Click Invite"] = true +L["Allows you to invite people by alt-clicking their names in chat."] = true +L["Invite links"] = true +L["Convets specified keywords to links that automatically invite message's author to group."] = true +L["Link Color"] = true +L["Invite Keywords"] = true --Databars L["Full value on Exp Bar"] = true diff --git a/ElvUI_SLE/locales/russian.lua b/ElvUI_SLE/locales/russian.lua index 62389e5..0fcf44b 100644 --- a/ElvUI_SLE/locales/russian.lua +++ b/ElvUI_SLE/locales/russian.lua @@ -274,6 +274,12 @@ L["Shows you which of docked chat tabs is currently selected."] = "Показы L["Chat history size"] = "Размер истории чата" L["Sets how many messages will be stored in history."] = "Кол-во сообщений, сохраняемых в истории чата." L["Following options determine which channels to save in chat history.\nNote: disabling a channel will immideately delete saved info for that channel."] = "Следующие опции задают каналы, которые будут сохраняться в истории чата.\nОбратите внимание: отключение канала тутже отчистит историю чата от сообщений из этого канала." +L["Alt-Click Invite"] = "Альт-клик для приглашения" +L["Allows you to invite people by alt-clicking their names in chat."] = "Позволяет приглашать людей в группу кликом по их именам с зажатым Alt." +L["Invite links"] = "Ссылки для приглашения" +L["Convets specified keywords to links that automatically invite message's author to group."] = "Превращает указаные слова в ссылки, клик по которым пригласит автора сообщения в группу." +L["Link Color"] = "Цвет ссылки" +L["Invite Keywords"] = "Ключевые слова для приглашения" --Databars L["Full value on Exp Bar"] = "Полное значение опыта" diff --git a/ElvUI_SLE/modules/chat/chat.lua b/ElvUI_SLE/modules/chat/chat.lua index ebab828..4ebe4e2 100644 --- a/ElvUI_SLE/modules/chat/chat.lua +++ b/ElvUI_SLE/modules/chat/chat.lua @@ -273,6 +273,8 @@ function C:Initialize() function C:ForUpdateAll() C.db = E.db.sle.chat C:GMIconUpdate() + C:CreateInvKeys() + C:SpamFilter() for i = 1, NUM_CHAT_WINDOWS do C:JustifyChat(i) end @@ -289,7 +291,7 @@ function C:Initialize() end --Teh Damage meter spam handle - C:InitDamageSpam() + C:InitLinks() --Combat Hide self:RegisterEvent("PLAYER_REGEN_ENABLED", "Combat") diff --git a/ElvUI_SLE/modules/chat/dpsSpam.lua b/ElvUI_SLE/modules/chat/dpsSpam.lua deleted file mode 100644 index 439fd5e..0000000 --- a/ElvUI_SLE/modules/chat/dpsSpam.lua +++ /dev/null @@ -1,169 +0,0 @@ -local SLE, T, E, L, V, P, G = unpack(select(2, ...)) -local C = SLE:GetModule("Chat") -local ItemRefTooltip = ItemRefTooltip -local ShowUIPanel = ShowUIPanel ---GLOBALS: UIParent, ChatFrame_AddMessageEventFilter, ChatFrame_RemoveMessageEventFilter - -C.Meterspam = false -C.ChannelEvents = { - "CHAT_MSG_CHANNEL", - "CHAT_MSG_GUILD", - "CHAT_MSG_OFFICER", - "CHAT_MSG_PARTY", - "CHAT_MSG_PARTY_LEADER", - "CHAT_MSG_INSTANCE_CHAT", - "CHAT_MSG_INSTANCE_CHAT_LEADER", - "CHAT_MSG_RAID", - "CHAT_MSG_RAID_LEADER", - "CHAT_MSG_SAY", - "CHAT_MSG_WHISPER", - "CHAT_MSG_WHISPER_INFORM", - "CHAT_MSG_YELL", -} - -C.spamFirstLines = { - "^Recount - (.*)$", --Recount - "^Skada: (.*) for (.*):$", -- Skada enUS - "^Skada: (.*) por (.*):$", -- Skada esES/ptBR - "^Skada: (.*) fur (.*):$", -- Skada deDE - "^Skada: (.*) pour (.*):$", -- Skada frFR - "^Skada: (.*) per (.*):$", -- Skada itIT - "^(.*) ? Skada ?? (.*):$", -- Skada koKR - "^Отчёт Skada: (.*), с (.*):$", -- Skada ruRU - "^Skada??(.*)?(.*):$", -- Skada zhCN - "^Skada:(.*)??(.*):$", -- Skada zhTW - "^(.*) Done for (.*)$", -- TinyDPS - "^Numeration: (.*)$", -- Numeration - "^Details!: (.*) for (.*)$" -- Details! -} -C.spamNextLines = { - "^(%d+)\. (.*)$", --Recount, Details! and Skada - "^(.*) (.*)$", --Additional Skada - "^Numeration: (.*)$", -- Numeration - "^[+-]%d+.%d", -- Numeration Deathlog Details - "^(%d+). (.*):(.*)(%d+)(.*)(%d+)%%(.*)%((%d+)%)$", -- TinyDPS - "^(.+) (%d-%.%d-%w)$", -- Skada 2 - '|c%x-|H.-|h(%[.-%])|h|r (%d-%.%d-%w %(%d-%.%d-%%%))', --Skada 3 -} -C.Meters = {} - -function C:filterLine(event, source, msg, ...) - local isSpam = false - for _, line in T.ipairs(C.spamNextLines) do - if msg:match(line) then - local curTime = T.GetTime() - for id, meter in T.ipairs(C.Meters) do - local elapsed = curTime - meter.time - if meter.src == source and meter.evt == event and elapsed < 1 then - -- found the meter, now check wheter this line is already in there - local toInsert = true - for a,b in T.ipairs(meter.data) do - if (b == msg) then - toInsert = false - end - end - if toInsert then T.tinsert(meter.data,msg) end - return true, false, nil - end - end - end - end - - for i, line in T.ipairs(C.spamFirstLines) do - local newID = 0 - if msg:match(line) then - local curTime = T.GetTime(); - if T.find(msg, "|cff(.+)|r") then - msg = T.gsub(msg, "|cff%w%w%w%w%w%w", "") - msg = T.gsub(msg, "|r", "") - end - for id,meter in T.ipairs(C.Meters) do - local elapsed = curTime - meter.time - if meter.src == source and meter.evt == event and elapsed < 1 then - newID = id - return true, true, T.format("|HSLD:%1$d|h|cFFFFFF00[%2$s]|r|h",newID or 0,msg or "nil") - end - end - - local newMeter = {src = source, evt = event, time = curTime, data = {}, title = msg} - T.tinsert(C.Meters, newMeter) - for id,meter in T.ipairs(C.Meters) do - if meter.src == source and meter.evt == event and meter.time == curTime then - newID = id - end - end - - return true, true, T.format("|HSLD:%1$d|h|cFFFFFF00[%2$s]|r|h",newID or 0,msg or "nil") - end - end - return false, false, nil -end - -function C:ParseChatEvent(event, msg, sender, ...) - local hide = false - for _,allevents in T.ipairs(C.ChannelEvents) do - if event == allevents then - local isRecount, isFirstLine, newMessage = C:filterLine(event, sender, msg) - if isRecount then - if isFirstLine then - msg = newMessage - else - hide = true - end - end - end - end - - if not hide then - return false, msg, sender, ... - end - return true -end - -function C:ParseLink(link, text, button, chatframe) - if C.db.dpsSpam then - local linktype, id = T.split(":", link) - if linktype == "SLD" then - local meterID = T.tonumber(id) - -- put stuff in the ItemRefTooltip from FrameXML - ShowUIPanel(ItemRefTooltip); - if ( not ItemRefTooltip:IsShown() ) then - ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE"); - end - ItemRefTooltip:ClearLines() - ItemRefTooltip:AddLine(C.Meters[meterID].title) - ItemRefTooltip:AddLine(T.format(L["Reported by %s"],C.Meters[meterID].src)) - for _,message in T.ipairs(C.Meters[meterID].data) do ItemRefTooltip:AddLine(message,1,1,1) end - ItemRefTooltip:Show() - end - end -end - -function C:SpamFilter() - if C.db.dpsSpam then - for _,event in T.ipairs(C.ChannelEvents) do - ChatFrame_AddMessageEventFilter(event, self.ParseChatEvent) - end - C.Meterspam = true - else - if C.Meterspam then - for _,event in T.ipairs(C.ChannelEvents) do - ChatFrame_RemoveMessageEventFilter(event, self.ParseChatEvent) - end - C.Meterspam = false - end - end -end - -function C:InitDamageSpam() - C:SpamFilter() - self:SecureHook("SetItemRef","ParseLink") - -- Borrowed from Deadly Boss Mods - do - local old = ItemRefTooltip.SetHyperlink -- we have to hook this function since the default ChatFrame code assumes that all links except for player and channel links are valid arguments for this function - function ItemRefTooltip:SetHyperlink(link, ...) - if link:sub(0, 4) == "SLD:" then return end - return old(self, link, ...) - end - end -end \ No newline at end of file diff --git a/ElvUI_SLE/modules/chat/links.lua b/ElvUI_SLE/modules/chat/links.lua new file mode 100644 index 0000000..85e9ba2 --- /dev/null +++ b/ElvUI_SLE/modules/chat/links.lua @@ -0,0 +1,233 @@ +local SLE, T, E, L, V, P, G = unpack(select(2, ...)) +local C = SLE:GetModule("Chat") +local ItemRefTooltip = ItemRefTooltip +local ShowUIPanel = ShowUIPanel +--GLOBALS: UIParent, ChatFrame_AddMessageEventFilter, ChatFrame_RemoveMessageEventFilter + +C.Meterspam = false +C.invLinksInit = false +C.ChannelEvents = { + "CHAT_MSG_CHANNEL", + "CHAT_MSG_GUILD", + "CHAT_MSG_OFFICER", + "CHAT_MSG_PARTY", + "CHAT_MSG_PARTY_LEADER", + "CHAT_MSG_INSTANCE_CHAT", + "CHAT_MSG_INSTANCE_CHAT_LEADER", + "CHAT_MSG_RAID", + "CHAT_MSG_RAID_LEADER", + "CHAT_MSG_SAY", + "CHAT_MSG_WHISPER", + "CHAT_MSG_WHISPER_INFORM", + "CHAT_MSG_YELL", +} +C.InvLinkEvents = { + "CHAT_MSG_CHANNEL", + "CHAT_MSG_GUILD", + "CHAT_MSG_OFFICER", + "CHAT_MSG_SAY", + "CHAT_MSG_WHISPER", + "CHAT_MSG_WHISPER_INFORM", + "CHAT_MSG_YELL", +} + +C.spamFirstLines = { + "^Recount - (.*)$", --Recount + "^Skada: (.*) for (.*):$", -- Skada enUS + "^Skada: (.*) por (.*):$", -- Skada esES/ptBR + "^Skada: (.*) fur (.*):$", -- Skada deDE + "^Skada: (.*) pour (.*):$", -- Skada frFR + "^Skada: (.*) per (.*):$", -- Skada itIT + "^(.*) ? Skada ?? (.*):$", -- Skada koKR + "^Отчёт Skada: (.*), с (.*):$", -- Skada ruRU + "^Skada??(.*)?(.*):$", -- Skada zhCN + "^Skada:(.*)??(.*):$", -- Skada zhTW + "^(.*) Done for (.*)$", -- TinyDPS + "^Numeration: (.*)$", -- Numeration + "^Details!: (.*) for (.*)$" -- Details! +} +C.spamNextLines = { + "^(%d+)\. (.*)$", --Recount, Details! and Skada + "^(.*) (.*)$", --Additional Skada + "^Numeration: (.*)$", -- Numeration + "^[+-]%d+.%d", -- Numeration Deathlog Details + "^(%d+). (.*):(.*)(%d+)(.*)(%d+)%%(.*)%((%d+)%)$", -- TinyDPS + "^(.+) (%d-%.%d-%w)$", -- Skada 2 + '|c%x-|H.-|h(%[.-%])|h|r (%d-%.%d-%w %(%d-%.%d-%%%))', --Skada 3 +} +C.Meters = {} + +local invKeys = {} +function C:CreateInvKeys() + local db = E.db.sle.chat.invite.keys + T.twipe(invKeys) + db = T.gsub(db, ',%s', ',') --remove spaces that follow a comma + for index = 1, T.select('#', T.split(",", db)) do + local key = T.select(index, T.split(",", db)) + if key then + invKeys[key] = true + print(key) + end + end +end + +function C:filterLine(event, source, msg, ...) + local isSpam = false + for _, line in T.ipairs(C.spamNextLines) do + if msg:match(line) then + local curTime = T.GetTime() + for id, meter in T.ipairs(C.Meters) do + local elapsed = curTime - meter.time + if meter.src == source and meter.evt == event and elapsed < 1 then + -- found the meter, now check wheter this line is already in there + local toInsert = true + for a,b in T.ipairs(meter.data) do + if (b == msg) then + toInsert = false + end + end + if toInsert then T.tinsert(meter.data,msg) end + return true, false, nil + end + end + end + end + + for i, line in T.ipairs(C.spamFirstLines) do + local newID = 0 + if msg:match(line) then + local curTime = T.GetTime(); + if T.find(msg, "|cff(.+)|r") then + msg = T.gsub(msg, "|cff%w%w%w%w%w%w", "") + msg = T.gsub(msg, "|r", "") + end + for id,meter in T.ipairs(C.Meters) do + local elapsed = curTime - meter.time + if meter.src == source and meter.evt == event and elapsed < 1 then + newID = id + return true, true, T.format("|HSLD:%1$d|h|cFFFFFF00[%2$s]|r|h",newID or 0,msg or "nil") + end + end + + local newMeter = {src = source, evt = event, time = curTime, data = {}, title = msg} + T.tinsert(C.Meters, newMeter) + for id,meter in T.ipairs(C.Meters) do + if meter.src == source and meter.evt == event and meter.time == curTime then + newID = id + end + end + + return true, true, T.format("|HSLD:%1$d|h|cFFFFFF00[%2$s]|r|h",newID or 0,msg or "nil") + end + end + return false, false, nil +end + +function C:ParseChatEvent(event, msg, sender, ...) + local hide = false + for _,allevents in T.ipairs(C.ChannelEvents) do + if event == allevents then + local isRecount, isFirstLine, newMessage = C:filterLine(event, sender, msg) + if isRecount then + if isFirstLine then + msg = newMessage + else + hide = true + end + end + end + end + + if not hide then + return false, msg, sender, ... + end + return true +end + +function C:ParseChatEventInv(event, msg, sender, ...) + local hex = E:RGBToHex(C.db.invite.color.r,C.db.invite.color.g,C.db.invite.color.b) + for _,allevents in T.ipairs(C.InvLinkEvents) do + if event == allevents then + for key,_ in pairs(invKeys) do + if T.find(msg, key) then + msg = T.gsub(msg, key, T.format("|Hinvite:"..sender.."|h"..hex.."[%s]|r|h", key)) + break + end + end + end + end + + return false, msg, sender, ... +end + +function C:SetItemRef(link, text, button, chatframe) + local linktype, id = T.split(":", link) + if C.db.dpsSpam then + if linktype == "SLD" then + local meterID = T.tonumber(id) + -- put stuff in the ItemRefTooltip from FrameXML + ShowUIPanel(ItemRefTooltip); + if ( not ItemRefTooltip:IsShown() ) then + ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE"); + end + ItemRefTooltip:ClearLines() + ItemRefTooltip:AddLine(C.Meters[meterID].title) + ItemRefTooltip:AddLine(T.format(L["Reported by %s"],C.Meters[meterID].src)) + for _,message in T.ipairs(C.Meters[meterID].data) do ItemRefTooltip:AddLine(message,1,1,1) end + ItemRefTooltip:Show() + return nil + end + end + if IsAltKeyDown() and linktype == "player" and E.db.sle.chat.invite.altInv then + InviteUnit(id) + return nil + elseif linktype == "invite" then + InviteUnit(id) + return nil + end + return self.hooks.SetItemRef(link, text, button) +end + +function C:SpamFilter() + if C.db.dpsSpam then + for _,event in T.ipairs(C.ChannelEvents) do + ChatFrame_AddMessageEventFilter(event, self.ParseChatEvent) + end + C.Meterspam = true + else + if C.Meterspam then + for _,event in T.ipairs(C.ChannelEvents) do + ChatFrame_RemoveMessageEventFilter(event, self.ParseChatEvent) + end + C.Meterspam = false + end + end + if C.db.invite.invLinks then + for _,event in T.ipairs(C.InvLinkEvents) do + ChatFrame_AddMessageEventFilter(event, self.ParseChatEventInv) + end + C.invLinksInit = true + else + if C.invLinksInit then + for _,event in T.ipairs(C.InvLinkEvents) do + ChatFrame_RemoveMessageEventFilter(event, self.ParseChatEventInv) + end + C.invLinksInit = false + end + end +end + +function C:InitLinks() + C:SpamFilter() + C:CreateInvKeys() + C:RawHook(nil, "SetItemRef", true) + -- Borrowed from Deadly Boss Mods + do + local old = ItemRefTooltip.SetHyperlink -- we have to hook this function since the default ChatFrame code assumes that all links except for player and channel links are valid arguments for this function + function ItemRefTooltip:SetHyperlink(link, ...) + if link:sub(0, 4) == "SLD:" then return end + if link:sub(0, 6) == "invite" then return end + return old(self, link, ...) + end + end +end \ No newline at end of file diff --git a/ElvUI_SLE/modules/chat/load_chat.xml b/ElvUI_SLE/modules/chat/load_chat.xml index f0c7650..0ede6db 100644 --- a/ElvUI_SLE/modules/chat/load_chat.xml +++ b/ElvUI_SLE/modules/chat/load_chat.xml @@ -1,6 +1,6 @@ <Ui xmlns="http://www.blizzard.com/wow/ui/"> <Script file='chat.lua'/> - <Script file='dpsSpam.lua'/> + <Script file='links.lua'/> <Script file='tabs.lua'/> <Script file='history.lua'/> </Ui> \ No newline at end of file diff --git a/ElvUI_SLE/options/chat/chat_c.lua b/ElvUI_SLE/options/chat/chat_c.lua index e422085..dcd3629 100644 --- a/ElvUI_SLE/options/chat/chat_c.lua +++ b/ElvUI_SLE/options/chat/chat_c.lua @@ -1,6 +1,6 @@ local SLE, T, E, L, V, P, G = unpack(select(2, ...)) local C = SLE:GetModule("Chat") -local NONE = NONE +local NONE, INVITE = NONE, INVITE local function configTable() if not SLE.initialized then return end local function CreateJustify(i) @@ -120,6 +120,54 @@ local function configTable() }, }, }, + invite = { + order = 15, + type = "group", + name = INVITE, + get = function(info) return E.db.sle.chat.invite[ info[#info] ] end, + set = function(info, value) E.db.sle.chat.invite[ info[#info] ] = value; end, + args = { + altInv = { + order = 1, + type = "toggle", + name = L["Alt-Click Invite"], + desc = L["Allows you to invite people by alt-clicking their names in chat."], + }, + invLinks = { + order = 2, + type = "toggle", + name = L["Invite links"], + desc = L["Convets specified keywords to links that automatically invite message's author to group."], + set = function(info, value) E.db.sle.chat.invite[ info[#info] ] = value; C:SpamFilter() end, + }, + color = { + type = 'color', + order = 3, + name = L["Link Color"], + hasAlpha = false, + disabled = function() return not E.db.sle.chat.invite.invLinks end, + get = function(info) + local t = E.db.sle.chat.invite[ info[#info] ] + local d = P.sle.chat.invite[info[#info]] + return t.r, t.g, t.b, d.r, d.g, d.b + end, + set = function(info, r, g, b) + E.db.sle.chat.tab[ info[#info] ] = {} + local t = E.db.sle.chat.invite[ info[#info] ] + t.r, t.g, t.b = r, g, b + end, + }, + keys = { + order = 4, + type = "input", + name = L["Invite Keywords"], + width = "full", + multiline = true, + disabled = function() return not E.db.sle.chat.invite.invLinks end, + set = function(info, value) E.db.sle.chat.invite[ info[#info] ] = value; C:CreateInvKeys() end, + }, + }, + }, }, } end