You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

393 lines
12 KiB

local ADDONNAME, WICB = ...
local corename = "WhisperInvite"
-- luacheck: globals LibStub WhisperInviteBasicDB
local core = LibStub("AceAddon-3.0"):GetAddon(corename)
LibStub("AceAddon-3.0"):NewAddon(WICB, ADDONNAME, "AceConsole-3.0", "AceEvent-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale(corename)
--local _G = _G
local tostring, find, sub, join, gmatch =
tostring, strfind, strsub, strjoin, string.gmatch
local type, select, pairs, wipe, unpack, tContains =
type, select, pairs, wipe, unpack, tContains
local lower = string.utf8lower or strlower
local channelTypes = {
normal = 1,
bnet = 2,
}
local defaults = {
global = {
--channels = {},
--bnet_channels = {},
},
profile = {
caseSensitive = false,
fullMatch = true,
plainMatch = true,
keywords = {},
keywordsCaseCache = {},
channels = {
CHAT_MSG_GUILD = false, -- L["CHAT_MSG_GUILD"] = "Guild"
CHAT_MSG_OFFICER = false, -- L["CHAT_MSG_OFFICER"] = "Guild officer"
CHAT_MSG_WHISPER = true, -- L["CHAT_MSG_WHISPER"] = "Whisper"
},
bnet_channels = {
CHAT_MSG_BN_CONVERSATION = false, -- L["CHAT_MSG_BN_CONVERSATION"] = "Chat"
CHAT_MSG_BN_INLINE_TOAST_BROADCAST = false, -- L["CHAT_MSG_BN_INLINE_TOAST_BROADCAST"] = "Status"
CHAT_MSG_BN_WHISPER = true, -- L["CHAT_MSG_BN_WHISPER"] = "Whisper"
},
},
}
function WICB:OnInitialize()
self.db = core:RegisterNamespace("WhisperInviteBasicDB", defaults)
self.db.RegisterCallback(self, "OnProfileChanged", "ResetCache")
self.db.RegisterCallback(self, "OnProfileCopied", "ResetCache")
-- NOTE: remove later
if type(WhisperInviteBasicDB) == "table" and ( type(WhisperInviteBasicDB.global) == "table" and not WhisperInviteBasicDB.global.imported or true ) then
local oldProfile = LibStub("AceDB-3.0"):New("WhisperInviteBasicDB", defaults, true).profile
local profile = self.db.profile
profile.caseSensitive = oldProfile.caseSensitive
profile.fullMatch = oldProfile.fullMatch
profile.plainMatch = oldProfile.plainMatch
profile.keywords = oldProfile.keywords
profile.keywordsCaseCache = oldProfile.keywordsCaseCache
profile.channels = oldProfile.channels
profile.bnet_channels = oldProfile.bnet_channels
WhisperInviteBasicDB.global = WhisperInviteBasicDB.global or {}
WhisperInviteBasicDB.global.imported = true
end
self:RegisterConfig()
end
function WICB:OnEnable()
self:RegisterAllChannels()
end
function WICB:OnDisable()
self:UnregisterAllChannels()
end
function WICB:RegisterAllChannels()
if not self:IsEnabled() then return end
local profile = self.db.profile
for channel, active in pairs(profile.channels) do
if active then
self:RegisterChannel(channel)
end
end
for channel, active in pairs(profile.bnet_channels) do
if active then
self:RegisterBNetChannel(channel)
end
end
end
local registeredChannels = {}
function WICB:RegisterChannel(channel)
if not self:IsEnabled() then return end
self:RegisterEvent(channel, "MessageIn", channelTypes.normal)
registeredChannels[lower(channel)] = true
--[===[@debug@
self:Printf("RegisterChannel: %s", channel)
--@end-debug@]===]
end
local registeredBNetChannels = {}
function WICB:RegisterBNetChannel(channel)
if not self:IsEnabled() then return end
self:RegisterEvent(channel, "MessageIn", channelTypes.bnet)
registeredBNetChannels[lower(channel)] = true
--[===[@debug@
self:Printf("RegisterBNetChannel: %s", channel)
--@end-debug@]===]
end
function WICB:UnregisterAllChannels()
for channel,registered in pairs(registeredChannels) do
if registered then
self:UnregisterChannel(channel)
end
end
for channel,registered in pairs(registeredBNetChannels) do
if registered then
self:UnregisterBNetChannel(channel)
end
end
end
function WICB:UnregisterChannel(channel)
self:UnregisterEvent(channel)
registeredChannels[lower(channel)] = false
--[===[@debug@
self:Printf("UnregisterChannel: %s", channel)
--@end-debug@]===]
end
function WICB:UnregisterBNetChannel(channel)
self:UnregisterEvent(channel)
registeredBNetChannels[lower(channel)] = false
--[===[@debug@
self:Printf("UnregisterBNetChannel: %s", channel)
--@end-debug@]===]
end
function WICB:MessageIn(channelType, event, ...)
if not self:IsEnabled() then return end
local msg = ...
--[===[@debug@
self:Printf("MessageIn: %q->%s", tostring(msg), tostring(channelType) )
--@end-debug@]===]
if self:KeywordMatch(msg) then
local result, code
if channelType == channelTypes.normal then
local _, name = ...
result, code = core:InvitePlayer(name)
elseif channelType == channelTypes.bnet then
--local presenceID = select(13, ...)
local _, _, _, _, _, _, _, _, _, _, _, _, presenceID = ...
result, code = core:InviteBNet(presenceID)
end
--[===[@debug@
self:Printf("Invite Sent: %s", result and "OK" or "Error: "..code )
--@end-debug@]===]
end
end
function WICB:KeywordMatch(msg)
local profile = self.db.profile
if not profile.caseSensitive then
msg = lower(msg)
end
if profile.fullMatch then
-- because false is better as nil^^
return not not tContains(profile.keywords, msg)
--return profile.keywords[msg]
else
local plainMatch = profile.plainMatch
if not plainMatch then
msg = " "..msg.." "
end
for _, keyword in pairs(profile.keywords) do
if find(msg, keyword, nil, plainMatch) then
return true
end
end
end
return false
end
local optionHandler = {}
function optionHandler:Set(info, value, ...)
local name = info[#info]
WICB.db.profile[name] = value
end
function optionHandler:Get(info, value, ...)
local name = info[#info]
return WICB.db.profile[name]
end
function optionHandler:SetCaseSensitive(info, value, ...)
self:Set(info, value, ...)
if value then
for i, keyword in pairs(WICB.db.profile.keywords) do
WICB.db.profile.keywords[i] = WICB.db.profile.keywordsCaseCache[keyword] or keyword
end
else
for i, keyword in pairs(WICB.db.profile.keywords) do
local lowerKeyword = lower(keyword)
WICB.db.profile.keywordsCaseCache[lowerKeyword] = keyword
WICB.db.profile.keywords[i] = lowerKeyword
end
end
end
function optionHandler:IsPlainMatchHidden(info, value)
return WICB.db.profile.fullMatch
end
do
local cacheChanged = {}
function optionHandler:ChangeMultiselectValues(info, value)
local name = info[#info]
WICB.db.profile[name][value] = type(WICB.db.profile[name][value]) == nil and true or nil
cacheChanged[name] = true
end
local cache = {}
function optionHandler:MultiselectValues(info)
local name = info[#info]
if not cache[name] or cacheChanged[name] then
cache[name] = wipe(cache[name] or {} )
for channel in pairs(WICB.db.profile[name]) do
cache[name][channel] = L[channel]
end
cacheChanged[name] = false
end
return cache[name]
end
end
function optionHandler:GetMultiselect(info, ...)
local key = select(select('#', ...), ...)
local name = info[#info]
return WICB.db.profile[name][key]
end
function optionHandler:SetMultiselect(info, key, ...)
local value = select(select('#', ...), ...)
local name = info[#info]
WICB.db.profile[name][key] = value
end
function optionHandler:SetChannel(info, key, ...)
self:SetMultiselect(info, key, ...)
if registeredChannels[lower(key)] then
WICB:UnregisterChannel(key)
elseif registeredBNetChannels[lower(key)] then
WICB:UnregisterBNetChannel(key)
else
if lower( sub(key, 0, 12) ) == "chat_msg_bn_" then
WICB:RegisterBNetChannel(key)
else
WICB:RegisterChannel(key)
end
end
end
do
local cacheChanged = {}
function optionHandler:SetMultilineText(info, value, ...)
local name = info[#info]
local profile = WICB.db.profile
local i = 1
local n = #profile[name]
for key in gmatch(value, "[^\n]+") do
if name == "keywords" and not profile.caseSensitive then
local orgKey = tostring(key)
key = lower(orgKey)
profile.keywordsCaseCache[key] = orgKey
end
profile[name][i] = tostring(key)
i = i+1
end
for j=i, n do
profile[name][j] = nil
end
cacheChanged[name] = true
end
local cache = {}
function optionHandler:GetMultilineText(info, ...)
local name = info[#info]
if cacheChanged[name] or not cache[name] then
cache[name] = join("\n", unpack(WICB.db.profile[name]) )
cacheChanged[name] = false
end
return cache[name]
end
function WICB:ResetCache()
wipe(cache)
wipe(cacheChanged)
end
end
local options = {
type = "group",
name = L["WhisperInvite Basic Settings"],
handler = optionHandler,
set = "Set",
get = "Get",
args = {
caseSensitive = {
type = "toggle",
name = L["Case sensitive"],
desc = L["Case sensitive keyword matching."],
set = "SetCaseSensitive",
order = 1,
},
fullMatch = {
type = "toggle",
name = L["Full match"],
desc = L["Message has to exactly match with the keyword."],
order = 2,
},
plainMatch = {
type = "toggle",
name = L["Pattern free matching"],
desc = L["Without pattern matching."],
hidden = "IsPlainMatchHidden",
order = 3,
},
keywords = {
type = "input",
name = L["Keywords"],
desc = L["Add here your invite keywords, one per line."],
multiline = 5,
set = "SetMultilineText",
get = "GetMultilineText",
width = "full",
order = 4,
},
channels = {
type = "multiselect",
name = L["Channels"],
desc = L["Channels where message will be checked for invite keywords."],
values = "MultiselectValues",
get = "GetMultiselect",
set = "SetChannel",
order = 5.1,
},
bnet_channels = {
type = "multiselect",
name = L["Battle.net Channels"],
desc = L["Battle.net Channels where message will be checked for invite keywords."],
values = "MultiselectValues",
get = "GetMultiselect",
set = "SetChannel",
order = 5.2,
},
},
}
function WICB:RegisterConfig()
LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable(ADDONNAME.."Options", options)
core:AddModuleConfig(ADDONNAME.."Options", L["Basic"])
end