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.

1132 lines
42 KiB

local ADDONNAME, WIC = ...
-- luacheck: globals LibStub ItemRefTooltip
LibStub("AceAddon-3.0"):NewAddon(WIC, ADDONNAME, "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale(ADDONNAME)
local _G = _G
local GetTime = GetTime
local find, split, lower, format, len, join =
strfind, strsplit, strlower, format, strlen, strjoin
local type, select, pairs, error, wipe =
type, select, pairs, error, wipe
-- L["CHAT_MSG_CHANNEL"] = "All Channels"
WIC.RegisteredModules = {}
WIC.RegisteredModulesWithLoadOnDemand = {}
WIC.RegisteredModulesDescription = {}
WIC.RegisteredModulesTranslatedName = {}
WIC.RegisteredModulesList = L["No Modules Registered"]
function WIC:RegisterModule(name, handle, addonName)
self.RegisteredModules[name] = handle
if type(addonName) == "string" then
self.RegisteredModulesWithLoadOnDemand[name] = addonName
end
end
function WIC:AddTranslatedNameToModule(name, localeName)
self.RegisteredModulesTranslatedName[name] = localeName
end
function WIC:AddDescriptionToModule(name, description)
self.RegisteredModulesDescription[name] = description
end
do-- Adding modules
WIC:RegisterModule("Basic", "WhisperInviteBasic", "WhisperInviteBasic")
WIC:AddTranslatedNameToModule("Basic", L["Basic"])
WIC:AddDescriptionToModule("Basic", L["Invite player when they whisper you with a defined keyword."])
WIC:RegisterModule("Advanced", "WhisperInviteAdvanced", "WhisperInviteAdvanced")
WIC:AddTranslatedNameToModule("Advanced" ,L["Advanced"])
WIC:AddDescriptionToModule("Advanced" ,L["Invite player when they whisper you with a defined keyword where they are allowed to use."])
-- Search for third-party Modules
-- Add this to your TOC-File:
--[[
RequiredDeps: WhisperInvite
X-WisperInvite-Name: ModuleName
X-WisperInvite-Handle: AddonName -> used as in LibStub("AceAddon-3.0"):GetAddon(AddonName, true) or Global Variable Name
X-WisperInvite-Version: Version -> See MODULEVERSION
X-WisperInvite-Description: Small Description
LoadOnDemand: 1 -> for when you only want be loaded when needed
--]]
--Name and Description supports localization e.g: X-WisperInvite-Description-deDE
-- Needed functions when not a AceAddon:
--[[
Module:Enable()
Module:Disable()
Module:IsEnabled()
--]]
local tonumber, tinsert =
tonumber, tinsert
local GetAddOnInfo, GetAddOnMetadata =
GetAddOnInfo, GetAddOnMetadata
local MODULEVERSION = 0
local locale = GAME_LOCALE or GetLocale()-- luacheck: ignore
for index=1, GetNumAddOns() do
local addonName, title, notes, enabled, loadable, reason, security = GetAddOnInfo(index)
local version = GetAddOnMetadata(addonName, "X-WisperInvite-Version")
if version and tonumber(version) == MODULEVERSION and loadable then
local name = GetAddOnMetadata(addonName, "X-WisperInvite-Name")
local localeName = GetAddOnMetadata(addonName, "X-WisperInvite-Name-"..locale) or name
local description = GetAddOnMetadata(addonName, "X-WisperInvite-Description-"..locale) or GetAddOnMetadata(addonName, "X-WisperInvite-Description") or L["No description for this module."]
local handle = GetAddOnMetadata(addonName, "X-WisperInvite-Handle")
if name and handle then
WIC:RegisterModule(name, handle, addonName)
WIC:AddTranslatedNameToModule(name, name)
end
if name and localeName then
WIC:AddTranslatedNameToModule(name, localeName)
end
if name and description then
WIC:AddDescriptionToModule(name, description)
else
WIC:AddDescriptionToModule(name, L["No description for this module."])
end
end
end
local list = {}
for moduleName in pairs(WIC.RegisteredModules) do
local name = moduleName--(WIC.RegisteredModulesTranslatedName[name] or name).."<"..name..">"
tinsert(list, name)
end
WIC.RegisteredModulesList = join(", ", unpack(list) )
end
local LF_QUEUE_PVP = "PVP"
local LF_QUEUES = {
['**'] = {
blockInvites = true,
sendMessage = false,
returnMessage = L["I'm currently in a LF-Queue"],
},
[LF_QUEUE_PVP] = {},
}
for id, name in pairs(LFG_CATEGORY_NAMES) do
LF_QUEUES[id] = {}
end
local defaults = {
global = {},
char = {
info = {
['*'] = 0,
},
infoMax = {
['*'] = 3,
setup = 5,
lfr_block = 9,
},
},
profile = {
active = true,
selectedModuleName = false,
convertGroupToRaid = true,
inviteThrottleTime = 10, -- seconds
queueProtection = LF_QUEUES,
statusProtection = {
AFK = {
blockInvites = false,
sendMessage = false,
returnMessage = L["I'm currently AFK"],
},
DND = {
blockInvites = false,
sendMessage = false,
returnMessage = L["I'm currently DND"],
},
},
},
}
WIC.TYPES = {
LINK = "whisperinvite",
H_LINK = "|Hwhisperinvite|h",
}
WIC.LOOKUP_LOCALIZED_CLASS_NAMES = {}
-- TODO: handling of profile.active
function WIC:OnInitialize()
self.db = LibStub("AceDB-3.0"):New("WhisperInviteCoreDB", defaults, true)
self.db.RegisterCallback(self, "OnProfileChanged", "CheckEnabledState")
self.db.RegisterCallback(self, "OnProfileCopied", "CheckEnabledState")
self:RegisterConfig()
-- To enable wisperinvite when disabled
self:RegisterChatCommand("wisperinviteenable", "Enable", true)
self:RegisterChatCommand("wienable", "Enable", true)
self:RegisterChatCommand("wisperinvitedisable", "Disable", true)
self:RegisterChatCommand("widisable", "Disable", true)
self:RegisterChatCommand("wi", "CMD", true)
self:RegisterChatCommand("wisperinvite", "CMD", true)
-- build localized lookup table for class names
for class, classLocalized in pairs(_G.LOCALIZED_CLASS_NAMES_MALE) do
self.LOOKUP_LOCALIZED_CLASS_NAMES[classLocalized] = class
end
for class, classLocalized in pairs(_G.LOCALIZED_CLASS_NAMES_FEMALE) do
self.LOOKUP_LOCALIZED_CLASS_NAMES[classLocalized] = class
end
self:SetEnabledState(self.db.profile.active)
if not self:IsEnabled() and self.db.char.info.enable < self.db.char.infoMax.enable then
self.db.char.info.enable = self.db.char.info.enable + 1
self:Print(L["You can run /wienable to enable WisperInvite."])
end
end
function WIC:Enable_ModuleHandling()
local showInfo = true
if type(self.db.profile.selectedModuleName) == "string" then
local isEnabled = self:EnableSelectedModule()
if isEnabled or self:SelectModuleIsEnabled() then
-- Module is registered and enabled
showInfo = false
end
end
if showInfo then
if self.db.char.info.setup < self.db.char.infoMax.setup then
self.db.char.info.setup = self.db.char.info.setup + 1
self:Print(L["Run /wi modules or /wi options to setup WisperInvite."])
end
end
end
function WIC:OnEnable()
self:Enable_ModuleHandling()
-- Hooking
self:SecureHook("ChatFrame_OnHyperlinkShow")
self:RawHook("HandleModifiedItemClick", true)
self:RawHook(ItemRefTooltip, "SetHyperlink", "ItemRefTooltip_SetHyperlink", true)
end
function WIC:ItemRefTooltip_SetHyperlink(frame, link, ...)
if link and find(link, self.TYPES.LINK) then
return false
else
return self.hooks[frame].SetHyperlink(frame, link, ...)
end
end
function WIC:HandleModifiedItemClick(link, ...)
if link and find(link, self.TYPES.H_LINK) then
return false
else
return self.hooks.HandleModifiedItemClick(link, ...)
end
end
function WIC:ChatFrame_OnHyperlinkShow(frame, linkData, link, button, ...)
if split(":", linkData) == self.TYPES.LINK then
local _, toonID, toonName, presenceName, presenceID, debug = split(":", linkData)
--[===[@debug@
if debug == "DEBUG" then
self:Printf("Invite: %s(%s), id:%s", toonName, presenceName, toonID)
return
end
--@end-debug@]===]
local result, code = self:InviteToon(toonID, toonName, presenceName, presenceID)
--[===[@debug@
self:Printf("Invite Sent: %s", result and "OK" or "Error: "..code )
--@end-debug@]===]
--else
--self.hooks.ChatFrame_OnHyperlinkShow(frame, linkData, link, button, ...)
end
end
function WIC:Disable_ModuleHandling()
self:DisableSelectedModule()
end
function WIC:OnDisable()
self:Disable_ModuleHandling()
end
function WIC:CheckEnabledState(event, db)
db = db or self.db
if db.profile.active then
--[===[@debug@
self:Print("Active")
--@end-debug@]===]
if not self:IsEnabled() then
--[===[@debug@
self:Print("Enable")
--@end-debug@]===]
self:Enable()
else
--[===[@debug@
self:Print("Enable->Module")
--@end-debug@]===]
self:Enable_ModuleHandling()
end
elseif self:IsEnabled() then
--[===[@debug@
self:Print("Disable")
--@end-debug@]===]
self:Disable()
end
end
do-- CMD
local InterfaceOptionsFrame_OpenToCategory, InterfaceOptionsFrameAddOnsListScrollBar =
InterfaceOptionsFrame_OpenToCategory, InterfaceOptionsFrameAddOnsListScrollBar
function WIC:CMD(input, editBox)
--GetArgs(str, numargs, startpos)
local arg1, lastPos = self:GetArgs(input, 1)
arg1 = arg1 and lower(arg1) or ""
if arg1 == "modules" then
local moduleName = self:GetArgs(input, 1, lastPos)
if self.RegisteredModules[moduleName] then
self:SelectModule(moduleName)
else
self:Printf(L["Usage: /wi modules moduleName (case sensitive)"])
self:Printf(L["Modules: %s"], self.RegisteredModulesList )
end
elseif arg1 == "enable" or arg1 == "on" or arg1 == L["enable"] or arg1 == L["on"] then
self.db.profile.active = true
self:NotifyChange()
WIC:CheckEnabledState("", self.db)
self:Print(L["Enabled"])
elseif arg1 == "disable" or arg1 == "off" or arg1 == L["disable"] or arg1 == L["off"] then
self.db.profile.active = false
self:NotifyChange()
WIC:CheckEnabledState("", self.db)
self:Print(L["Disabled"])
elseif arg1 == "toggle" or arg1 == L["toggle"] then
self.db.profile.active = not self.db.profile.active
self:NotifyChange()
WIC:CheckEnabledState("", self.db)
if self.db.profile.active then
self:Print(L["Enabled"])
else
self:Print(L["Disabled"])
end
elseif not arg1 or arg1 == "" or arg1 == "help" or arg1 == "usage" or arg1 == L["help"] or arg1 == L["usage"] then
self:Print(L["Usage: /wi <command>\nCommands: modules, options"])
elseif arg1 == "options" or arg1 == "op" then
-- Load InterfaceOptionsFrameAddOns frame...
InterfaceOptionsFrame_OpenToCategory(ADDONNAME)
-- Let's scroll down, so your page can be open
InterfaceOptionsFrameAddOnsListScrollBar:SetValue(select(2, InterfaceOptionsFrameAddOnsListScrollBar:GetMinMaxValues() ) )
InterfaceOptionsFrame_OpenToCategory(ADDONNAME)
else
LibStub("AceConfigCmd-3.0").HandleCommand(self, "wi", ADDONNAME.."Options", input)
end
end
end
function WIC:SelectModule(moduleName)
if self.RegisteredModules[moduleName] then
local profile = self.db.profile
profile.selectedModuleName = moduleName
if profile.active then
return self:EnableSelectedModule()
end
return true
end
return false
end
do-- Module handling
local IsAddOnLoaded, LoadAddOn =
IsAddOnLoaded, LoadAddOn
local oldModule
function WIC:EnableSelectedModule()
local name = self.db.profile.selectedModuleName
local addonName = self.RegisteredModulesWithLoadOnDemand[name]
if name and addonName then
if not IsAddOnLoaded(addonName) then
local loaded, resason = LoadAddOn(self.RegisteredModulesWithLoadOnDemand[name])
if not loaded then
self:Printf(L["Can't load module %s because %s"], name, _G["ADDON_"..resason] or resason)
return false, resason
end
end
local handle = self.RegisteredModules[name]
local selectModule = LibStub("AceAddon-3.0"):GetAddon(handle, true) or _G[handle]
if selectModule and type(selectModule.Enable) == "function" then
if oldModule and type(oldModule.Disable) == "function" then
oldModule:Disable()
end
oldModule = selectModule
return selectModule:Enable()
else
self:Print(not selectModule and L["Module not found."] or L["Module hasn't needed functions."] )
return false
end
else
self:Printf(L["Can't load module. %s"], (not name and L["No module selected!"] or not addonName and L["Addon name not found!"] or "") )
return false
end
end
function WIC:SelectModuleIsEnabled()
local activeModule = oldModule
if not activeModule then
local name = self.db.profile.selectedModuleName
local handle = self.RegisteredModules[name]
activeModule = LibStub("AceAddon-3.0"):GetAddon(handle, true) or _G[handle]
end
if type(activeModule.IsEnabled) == "function" then
return activeModule:IsEnabled()
end
return false
end
end
function WIC:DisableSelectedModule()
local name = self.db.profile.selectedModuleName
--[===[@debug@
self:Print("Disable Module: ", name)
--@end-debug@]===]
if name then
local handle = self.RegisteredModules[name]
local selectModule = LibStub("AceAddon-3.0"):GetAddon(handle, true) or _G[handle]
--[===[@debug@
self:Print("selectModule: ", selectModule, ", type: ", type(selectModule), ", selectModule.Disable type: ", type(selectModule.Disable))
--@end-debug@]===]
if selectModule and type(selectModule.Disable) == "function" then
selectModule:Disable()
--[===[@debug@
self:Print("Module disabled")
--@end-debug@]===]
end
end
end
do-- CanInvite
local IsInGroup, UnitIsGroupLeader, UnitIsGroupAssistant, GetInstanceInfo =
IsInGroup, UnitIsGroupLeader, UnitIsGroupAssistant, GetInstanceInfo
local LE_PARTY_CATEGORY_INSTANCE = LE_PARTY_CATEGORY_INSTANCE
function WIC:CanInvite()
--if _G.IsInGroup(_G.LE_PARTY_CATEGORY_INSTANCE) and select(3, _G.GetInstanceInfo() ) ~= 14 then
--if select(3, _G.GetInstanceInfo() ) ~= 7 then
if IsInGroup(LE_PARTY_CATEGORY_INSTANCE) then
-- we can not invite when in a instance group or can we?
local _, _, difficultyID = GetInstanceInfo()
if difficultyID ~= 7 -- LFR
and difficultyID ~= 17 -- LFR 10-30
and difficultyID ~= 1 -- Normal
and difficultyID ~= 2 --[[Heroic]] then
-- Print infos only a limit time
if self.db.char.info.lfr_block < self.db.char.infoMax.lfr_block then
self:Printf(L["You are in an instance group and not in LFR or LFG group. When you can invite here players let me know it."])
local name, instanceType, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceMapID, instanceGroupSize
name, instanceType, difficultyID, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceMapID, instanceGroupSize = _G.GetInstanceInfo()
local info = "instanceType:"..instanceType..", difficultyID:"..difficultyID..", difficultyName:"..difficultyName
self:Printf(L["And show me this infos: %s"], info)
self.db.char.info.lfr_block = self.db.char.info.lfr_block + 1
end
-- hope nothing explodes..
return UnitIsGroupLeader("player") or UnitIsGroupAssistant("player") or not IsInGroup()
end
return false
else
return UnitIsGroupLeader("player") or UnitIsGroupAssistant("player") or not IsInGroup()
end
end
end
do-- CheckGroupSize
local ConvertToRaid, IsInRaid, GetNumGroupMembers
= ConvertToRaid, IsInRaid, GetNumGroupMembers
local LE_PARTY_CATEGORY_HOME, MAX_PARTY_MEMBERS
= LE_PARTY_CATEGORY_HOME, MAX_PARTY_MEMBERS
function WIC:CheckGroupSize()
if not IsInRaid() and GetNumGroupMembers(LE_PARTY_CATEGORY_HOME) > MAX_PARTY_MEMBERS then
if self.db.profile.convertGroupToRaid then
ConvertToRaid()
return true
else
return false
end
end
return true
end
end
do-- IsQueueProtected / IsStatusProtected
local BNSendWhisper, SendChatMessage, GetLFGMode, GetMaxBattlefieldID, GetBattlefieldStatus, UnitIsAFK, UnitIsDND, UnitIsUnit, GetCVar, SetCVar =
BNSendWhisper, SendChatMessage, GetLFGMode, GetMaxBattlefieldID, GetBattlefieldStatus, UnitIsAFK, UnitIsDND, UnitIsUnit, GetCVar, SetCVar
local function sendReturnMessage(name, presenceID, message)
if presenceID then
BNSendWhisper(presenceID, message)
elseif name and not UnitIsUnit("player", name) then
SendChatMessage(message, "WHISPER", nil, name)
end
end
function WIC:IsQueueProtected(name, presenceName, presenceID)
if not name or (name and presenceName and not presenceID) or (name and presenceID and not presenceName) then error("Usage: IsQueueProtected(name) or IsQueueProtected(toonName, presenceName, presenceID") end
local printName = presenceName and format(L["%s (%s)"], presenceName or L["<No name given>"], name or L["<No toon name given>"]) or name
-- Look for queue Protection
for id, data in pairs(self.db.profile.queueProtection) do
if type(id) == "number" and data.blockInvites then
local mode = GetLFGMode(id)
if mode then
if data.sendMessage and len(data.returnMessage) > 1 then
if presenceID then
sendReturnMessage(name, presenceID, data.returnMessage)
else
sendReturnMessage(name, nil, data.returnMessage)
end
end
self:Printf(L["Your are in a LF-Queue. Can't invite %s"], printName)
return true
end
elseif id == LF_QUEUE_PVP and data.blockInvites then
for i=1, GetMaxBattlefieldID() do
local status = GetBattlefieldStatus(i)
if status ~= "none" then
if data.sendMessage and len(data.returnMessage) > 1 then
if presenceID then
sendReturnMessage(name, presenceID, data.returnMessage)
else
sendReturnMessage(name, nil, data.returnMessage)
end
end
self:Printf(L["Your are in a LF-Queue. Can't invite %s"], printName)
return true
end
end
end
end
return false
end
function WIC:IsStatusProtected(name, presenceName, presenceID)
if not name or (name and presenceName and not presenceID) or (name and presenceID and not presenceName) then error("Usage: IsQueueProtected(name) or IsQueueProtected(toonName, presenceName, presenceID") end
local printName = presenceName and format(L["%s (%s)"], presenceName or L["<No name given>"], name or L["<No toon name given>"]) or name
if UnitIsAFK("player") then
local afkProtection = self.db.profile.statusProtection.AFK
if afkProtection.sendMessage then
local returnMessage = afkProtection.returnMessage
if len(returnMessage) > 1 then
local autoClearAFK = GetCVar("autoClearAFK")
if autoClearAFK ~= "0" then
SetCVar("autoClearAFK", "0")
end
if presenceID then
sendReturnMessage(name, presenceID, returnMessage)
else
sendReturnMessage(name, nil, returnMessage)
end
-- re-set autoClearAFK value
SetCVar("autoClearAFK", autoClearAFK)
end
end
if afkProtection.blockInvites then
self:Printf(L["Your are AFK. Invite to %s was not sent."], printName)
return true
end
end
if UnitIsDND("player") then
local dndProtection = self.db.profile.statusProtection.DND
if dndProtection.sendMessage then
local returnMessage = dndProtection.returnMessage
if len(returnMessage) > 1 then
if presenceID then
sendReturnMessage(name, presenceID, returnMessage)
else
sendReturnMessage(name, nil, returnMessage)
end
end
end
if dndProtection.blockInvites then
self:Printf(L["Your are DND. Haven't send an invite to %s"], printName)
return true
end
end
return false
end
end
--- InviteErrorCodeList
-- 1: Player is not allowed to invite other players
-- 2: No BNet/RealID friend is online with this presenceID
-- 3: Invalid parameters
-- 4: Maximal group size reached
-- 5: No WoW toon is online
-- 6: Invite for this key was throttled
-- 7: Invite was blocked because of a LF-Queue or Status (AFK/DND)
do-- InvitePlayer
local InviteUnit, Ambiguate =
InviteUnit, Ambiguate
local playerName_Throttle = {}
--- Invite player with name
-- @param (String) name
-- @return1 (Boolean) true == Invite sent, false == Invite not possible
-- @return2 (Number) errorCode @see InviteErrorCodeList
function WIC:InvitePlayer(name)
if not name then
return false, 3
end
if self:CanInvite() then
if self:IsQueueProtected(name) or self:IsStatusProtected(name) then
return false, 7
elseif self:CheckGroupSize() then
local time = GetTime()
if (playerName_Throttle[name] or 0) < time then
playerName_Throttle[name] = time + self.db.profile.inviteThrottleTime
--_G.InviteUnit( self:UniformPlayerName(name) )
InviteUnit( Ambiguate(name, "none") )
return true
else
return false, 6
end
else
self:Printf(L["Maximal group size reached. Can't invite %s"], name)
return false, 4
end
else
return false, 1
end
end
end
do-- InviteBNet
local BNGetFriendIndex, BNGetNumFriendGameAccounts, BNGetFriendGameAccountInfo, BNGetFriendInfo, UnitFactionGroup =
BNGetFriendIndex, BNGetNumFriendGameAccounts, BNGetFriendGameAccountInfo, BNGetFriendInfo, UnitFactionGroup
local BNET_CLIENT_WOW, RAID_CLASS_COLORS =
BNET_CLIENT_WOW, RAID_CLASS_COLORS
local toonCache = {}
--- Invite player over Battle.net
-- @paramsig presenceID [, friendIndex]
-- @paramsig nil, friendIndex
-- @param (presenceID) presenceID
-- @param (Number) friendIndex
-- @return1 (Boolean) true: Invite sent, false: Invite not possible
-- @return2 (Number) errorCode @see InviteErrorCodeList
--[===[@debug@
function WIC:InviteBNet(presenceID, friendIndex, debug)
--@end-debug@]===]
--@non-debug@
function WIC:InviteBNet(presenceID, friendIndex)
--@end-non-debug@
if not self:CanInvite() then
return false, 1
end
if type(friendIndex) ~= "number" and presenceID then
friendIndex = BNGetFriendIndex(presenceID)
if not friendIndex then
return false, 2
end
elseif type(friendIndex) ~= "number" then
return false, 3
end
local numToons = BNGetNumFriendGameAccounts(friendIndex)
local toonCount = 0
for toonIndex=1, numToons do
local hasFocus, toonName, client, realmName, realmID, faction, race, classLocalized, guild, zoneName, level, gameText, broadcastText, broadcastTime, canSoR, toonID = BNGetFriendGameAccountInfo(friendIndex, toonIndex)
if client == BNET_CLIENT_WOW then
toonCount = toonCount + 1
toonCache[toonCount] = toonCache[toonCount] or {}
toonCache[toonCount].class = self.LOOKUP_LOCALIZED_CLASS_NAMES[classLocalized] or "WARRIOR"
toonCache[toonCount].toonID = toonID
toonCache[toonCount].faction = faction
toonCache[toonCount].toonName = toonName
toonCache[toonCount].realmName = realmName
toonCache[toonCount].presenceID, toonCache[toonCount].presenceName = BNGetFriendInfo(friendIndex)
end
end
--[===[@debug@
if debug then
toonCount = 3
toonCache[1] = toonCache[1] or {}
toonCache[1].class = "DRUID"
toonCache[1].toonID = 0
toonCache[1].faction = "Alliance"
toonCache[1].toonName = "Areko"
toonCache[1].realmName = "Alleria"
toonCache[1].presenceName = "Areko#0000"
toonCache[1].presenceID = 0
toonCache[2] = toonCache[2] or {}
toonCache[2].class = "HUNTER"
toonCache[2].toonID = 0
toonCache[2].faction = "Alliance"
toonCache[2].toonName = "Tânuri"
toonCache[2].realmName = "Alleria"
toonCache[2].presenceName = "Tanuri#0000"
toonCache[2].presenceID = 0
toonCache[3] = toonCache[3] or {}
toonCache[3].class = "MAGE"
toonCache[3].toonID = 0
toonCache[3].faction = "Horde"
toonCache[3].toonName = "Keks"
toonCache[3].realmName = "Alleria"
toonCache[3].presenceName = "Keks#0000"
toonCache[3].presenceID = 0
end
--@end-debug@]===]
if toonCount > 0 then
if toonCount == 1 then
local toon = toonCache[1]
return self:InviteToon(toon.toonID, toon.toonName, toon.presenceName, toon.presenceID)
else
-- \124 > |
local linkTemplate = "[|H%s:%s|h%s|h]"
local colourTemplate = "|c%s%s|r"
local alliance
local horde
local colours = _G.CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS
for i=1,toonCount do
local toon = toonCache[i]
local linkData = toon.toonID..":"..toon.toonName..":"..toon.presenceName..":"..toon.presenceID
local name = self:UniformPlayerName(toon.toonName, toon.realmName)
local colour = colours[toon.class].colorStr or "FFFFFFFF"
--[===[@debug@
if debug then
linkData = linkData..":DEBUG"
end
--@end-debug@]===]
local msg = format(colourTemplate, colour, format(linkTemplate, self.TYPES.LINK, linkData, name) )
if toon.faction == "Horde" then
horde = horde and horde..", "..msg or msg
elseif toon.faction == "Alliance" then
alliance = alliance and alliance..", "..msg or msg
else
horde = horde and horde..", "..msg or msg
alliance = alliance and alliance..", "..msg or msg
end
end
local factionGroup = UnitFactionGroup("player")
self:Printf(L["%s is with more then one toon online. Choose which toons should be invited. Click on the name to invite."], toonCache[1].presenceName )
if factionGroup == "Alliance" then
if alliance then
self:Printf(L["Alliance toons: %s"], alliance )
end
if horde then
self:Printf(L["Horde toons: %s"], horde )
end
else
if horde then
self:Printf(L["Horde toons: %s"], horde )
end
if alliance then
self:Printf(L["Alliance toons: %s"], alliance )
end
end
return true, toonCount
end
else
local _, presenceName = BNGetFriendInfo(friendIndex)
self:Printf(L["%s is not online in World of Warcraft."], presenceName)
return false, 5
end
end
end
do-- InviteToon
local BNInviteFriend = BNInviteFriend
local battleNet_Throttle = {}
function WIC:InviteToon(toonID, toonName, presenceName, presenceID)
if not toonID then
return false, 3
end
if self:IsQueueProtected(toonName, presenceName, presenceID) or self:IsStatusProtected(toonName, presenceName, presenceID) then
return false, 7
elseif self:CheckGroupSize() then
local time = GetTime()
if (battleNet_Throttle[toonID] or 0) < time then
battleNet_Throttle[toonID] = time + self.db.profile.inviteThrottleTime
BNInviteFriend( toonID )
return true
else
return false, 6
end
else
self:Printf(L["Maximal group size reached. Can't invite %s"], format(L["%s (%s)"], presenceName or L["<No name given>"], toonName or L["<No toon name given>"]) )
return false, 4
end
end
end
--- Returns uniformed player or guild name
-- @paramsig playerName [, realmOverride]
-- @param (String) playerName/guildName
-- @param (String, optional) realmOverride
--
-- @return "Name-Realm", "Name", "Realm"
do
local homeRealm = GetRealmName()
local dash = "-"
function WIC:UniformPlayerName(playerName, realmOverride)
local name = playerName
local realm = homeRealm
if find(playerName, dash) then
name, realm = split(dash, playerName, 2)
end
realm = realmOverride or realm
return name..dash..realm, name, realm
end
function WIC:UniformGuildName(guildName, realmOverride)
-- same as player
return self:UniformPlayerName(guildName, realmOverride)
end
end
local optionHandler = {}
function optionHandler:Set(info, value, ...)
local name = info[#info]
WIC.db.profile[name] = value
end
function optionHandler:Get(info, value, ...)
local name = info[#info]
return WIC.db.profile[name]
end
function optionHandler:SetActive(info, value, ...)
self:Set(info, value, ...)
WIC:CheckEnabledState("", WIC.db)
end
function optionHandler:SetModule(info, value, ...)
self:Set(info, value, ...)
if WIC:IsEnabled() then
WIC:EnableSelectedModule()
end
end
function optionHandler:SetQueue(info, value, ...)
local name = info[#info]
WIC.db.profile.queueProtection[info.arg][name] = value
end
function optionHandler:GetQueue(info, value, ...)
local name = info[#info]
return WIC.db.profile.queueProtection[info.arg][name]
end
function optionHandler:SetStatus(info, value, ...)
local name = info[#info]
WIC.db.profile.statusProtection[info.arg][name] = value
end
function optionHandler:GetStatus(info, value, ...)
local name = info[#info]
return WIC.db.profile.statusProtection[info.arg][name]
end
function optionHandler:IsReturnMessageHidden(info)
return not WIC.db.profile.queueProtection[info.arg].sendMessage
end
local options = {
type = "group",
name = L["WisperInvite Core Settings"],
handler = optionHandler,
set = "Set",
get = "Get",
args = {
active = {
type = "toggle",
name = L["Active"],
desc = L["Is this profile enabled."],
width = "full",
set = "SetActive",
order = 1,
},
selectedModuleName = {
type = "select",
name = L["Active module"],
desc = L["Choose active module."],
values = WIC.RegisteredModulesTranslatedName,
set = "SetModule",
order = 2,
},
convertGroupToRaid = {
type = "toggle",
name = L["Auto convert"],
desc = L["Convert group to raid when group has reached maximal size."],
width = "full",
order = 3,
},
inviteThrottleTime = {
type = "range",
name = L["Invite Throttle"],
desc = L["Delay(seconds) needed between to invites of the same player before, WhisperInvite can send a new invite."],
min = 0.5,
max = 120,
softMin = 6,
softMax = 30,
bigStep = 1,
step = 0.1,
--width = "full",
order = 4,
},
statusProtection = {
type = "group",
inline = true,
name = L["AFK/DND Protection"],
set = "SetStatus",
get = "GetStatus",
args = {
descriptionText = {
type = "description",
name = L["Choose when you don't want to automatic invite other players when you are AFK or DND.\nAnd if to send a message."],
fontSize = "normal",
order = 0,
},
AFK = {
type = "group",
name = DEFAULT_AFK_MESSAGE,
inline = true,
args = {
blockInvites = {
type = "toggle",
name = L["Block invites"],
desc = L["Block invites when you are AFK"],
arg = "AFK",
order = 1,
},
sendMessage = {
type = "toggle",
name = L["Send an answer"],
desc = L["Send a message to inform that you are AFK."],
arg = "AFK",
order = 2,
},
returnMessage = {
type = "input",
name = L["Answer"],
desc = L["The message you will send."],
width = "full",
arg = "AFK",
order = 3,
},
},
},
DND = {
type = "group",
name = DEFAULT_DND_MESSAGE,
inline = true,
args = {
blockInvites = {
type = "toggle",
name = L["Block invites"],
desc = L["Block invites when you are DND"],
arg = "DND",
order = 1,
},
sendMessage = {
type = "toggle",
name = L["Send an answer"],
desc = L["Send a message to inform that you are DND."],
arg = "DND",
order = 2,
},
returnMessage = {
type = "input",
name = L["Answer"],
desc = L["The message you will send."],
width = "full",
arg = "DND",
order = 3,
},
},
},
},
},
queueProtection = {
type = "group",
inline = true,
name = L["LF-Queue Protection"],
set = "SetQueue",
get = "GetQueue",
args = {},
},
},
}
local updateConfig
do-- updateConfig
local LFG_CATEGORY_NAMES, QUEUED_STATUS_UNKNOWN, PVP =
LFG_CATEGORY_NAMES, QUEUED_STATUS_UNKNOWN, PVP
function updateConfig()
local args = wipe(options.args.queueProtection.args)
for id in pairs(WIC.db.profile.queueProtection) do
local name
if type(id) == "number" then
name = LFG_CATEGORY_NAMES[id] or QUEUED_STATUS_UNKNOWN
else
name = PVP
end
args[name] = {
type = "group",
name = name,
inline = true,
args = {
blockInvites = {
type = "toggle",
name = L["Block invites"],
desc = format(L["When in the %q Queue block invites."], name),
arg = id,
order = 1,
},
sendMessage = {
type = "toggle",
name = L["Send an answer"],
desc = L["Send a message to inform that you have not send an invite because your are in a LF-Queue."],
arg = id,
order = 2,
},
returnMessage = {
type = "input",
name = L["Answer"],
desc = L["The message you will send."],
arg = id,
--hidden = "IsReturnMessageHidden",
width = "full",
order = 3,
},
},
}
end
args.descriptionText = {
type = "description",
name = L["Choose when you don't want to automatic invite other players when you are in a LF-Queue.\n"],
fontSize = "normal",
order = 0,
}
end
end
local configIsRegistered = false
local unregisteredConfigs = {}
function WIC:RegisterConfig()
updateConfig()
LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable(ADDONNAME.."Options", options)
LibStub("AceConfigDialog-3.0"):AddToBlizOptions(ADDONNAME.."Options", ADDONNAME)
LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable(ADDONNAME.."Profile", LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) )
LibStub("AceConfigDialog-3.0"):AddToBlizOptions(ADDONNAME.."Profile", L["Profile"], ADDONNAME)
configIsRegistered = true
for appName, name in pairs(unregisteredConfigs) do
self:AddModuleConfig(appName, name)
end
wipe(unregisteredConfigs)
end
--- Use to register your DB as namespace of the core DB
-- @param (String) name
-- @param (table) defaults
function WIC:RegisterNamespace(name, namespaceDefaults)
if type(namespaceDefaults) ~= "table" then
namespaceDefaults = nil
end
return self.db:RegisterNamespace(name, namespaceDefaults)
end
--- Add your config to BlizzOptions as child of WhisperInvite
-- @param (String) appName - same as used in AceConfigRegistry:RegisterOptionsTable()
-- @param (String) name - Display name
function WIC:AddModuleConfig(appName, name)
if configIsRegistered then
if appName and LibStub("AceConfigRegistry-3.0"):GetOptionsTable(appName) then
LibStub("AceConfigDialog-3.0"):AddToBlizOptions(appName, name or appName, ADDONNAME)
return true
else
return false
end
else
unregisteredConfigs[appName] = name or appName
end
end
function WIC:NotifyChange()
LibStub("AceConfigRegistry-3.0"):NotifyChange(ADDONNAME.."Options")
end