330 lines
10 KiB
Lua
330 lines
10 KiB
Lua
|
local MAJOR, MINOR = "LibElvUIPlugin-1.0", 36
|
|||
|
local lib = _G.LibStub:NewLibrary(MAJOR, MINOR)
|
|||
|
if not lib then return end
|
|||
|
-- GLOBALS: ElvUI
|
|||
|
|
|||
|
--[[----------------------------
|
|||
|
Plugin Table Format: (for reference only).
|
|||
|
{
|
|||
|
name - name of the plugin
|
|||
|
callback - callback to call when ElvUI_OptionsUI is loaded
|
|||
|
isLib - plugin is a library
|
|||
|
version - version of the plugin (pulls version info from metadata, libraries can define their own)
|
|||
|
|
|||
|
-- After new version recieved from another user:
|
|||
|
old - plugin is old version
|
|||
|
newversion - newer version number
|
|||
|
}
|
|||
|
|
|||
|
LibElvUIPlugin API:
|
|||
|
RegisterPlugin(name, callback, isLib, libVersion)
|
|||
|
-- Registers a module with the given name and option callback:
|
|||
|
name - name of plugin
|
|||
|
verion - version number
|
|||
|
isLib - plugin is a library
|
|||
|
libVersion - plugin library version (optional, defaults to 1)
|
|||
|
|
|||
|
HookInitialize(table, function)
|
|||
|
-- Posthook ElvUI Initialize function:
|
|||
|
table - addon table
|
|||
|
function - function to call after Initialize (may be a string, that exists on the addons table: table['string'])
|
|||
|
----------------------------]]--
|
|||
|
|
|||
|
local assert, pairs, ipairs, strlen = assert, pairs, ipairs, strlen
|
|||
|
local tonumber, strmatch, strsub, tinsert = tonumber, strmatch, strsub, tinsert
|
|||
|
local format, wipe, type, gmatch, gsub, ceil = format, wipe, type, gmatch, gsub, ceil
|
|||
|
|
|||
|
local hooksecurefunc = hooksecurefunc
|
|||
|
local GetAddOnMetadata = GetAddOnMetadata
|
|||
|
local GetNumGroupMembers = GetNumGroupMembers
|
|||
|
local GetLocale, IsInGuild = GetLocale, IsInGuild
|
|||
|
local CreateFrame, IsAddOnLoaded = CreateFrame, IsAddOnLoaded
|
|||
|
local IsInRaid, IsInGroup = IsInRaid, IsInGroup
|
|||
|
local C_ChatInfo_RegisterAddonMessagePrefix = C_ChatInfo.RegisterAddonMessagePrefix
|
|||
|
local C_ChatInfo_SendAddonMessage = C_ChatInfo.SendAddonMessage
|
|||
|
local LE_PARTY_CATEGORY_HOME = LE_PARTY_CATEGORY_HOME
|
|||
|
local LE_PARTY_CATEGORY_INSTANCE = LE_PARTY_CATEGORY_INSTANCE
|
|||
|
local UNKNOWN = UNKNOWN
|
|||
|
|
|||
|
lib.prefix = "ElvUIPluginVC"
|
|||
|
lib.plugins = {}
|
|||
|
lib.groupSize = 0
|
|||
|
lib.index = 0
|
|||
|
|
|||
|
local MSG_OUTDATED = "Your version of %s %s is out of date (latest is version %s). You can download the latest version from http://www.tukui.org"
|
|||
|
local HDR_INFORMATION = "LibElvUIPlugin-1.0.%d - Plugins Loaded (Green means you have current version, Red means out of date)"
|
|||
|
local INFO_BY = "by"
|
|||
|
local INFO_VERSION = "Version:"
|
|||
|
local INFO_NEW = "Newest:"
|
|||
|
local LIBRARY = "Library"
|
|||
|
|
|||
|
local locale = GetLocale()
|
|||
|
if locale == "deDE" then
|
|||
|
MSG_OUTDATED = "Deine Version von %s %s ist veraltet (akutelle Version ist %s). Du kannst die aktuelle Version von http://www.tukui.org herunterrladen."
|
|||
|
HDR_INFORMATION = "LibElvUIPlugin-1.0.%d - Plugins geladen (Grün bedeutet du hast die aktuelle Version, Rot bedeutet es ist veraltet)"
|
|||
|
INFO_BY = "von"
|
|||
|
INFO_VERSION = "Version:"
|
|||
|
INFO_NEW = "Neuste:"
|
|||
|
LIBRARY = "Bibliothek"
|
|||
|
elseif locale == "ruRU" then
|
|||
|
MSG_OUTDATED = "Ваша версия %s %s устарела (последняя версия %s). Вы можете скачать последнюю версию на http://www.tukui.org"
|
|||
|
HDR_INFORMATION = "LibElvUIPlugin-1.0.%d - загруженные плагины (зеленый означает, что у вас последняя версия, красный - устаревшая)"
|
|||
|
INFO_BY = "от"
|
|||
|
INFO_VERSION = "Версия:"
|
|||
|
INFO_NEW = "Последняя:"
|
|||
|
LIBRARY = "Библиотека"
|
|||
|
elseif locale == "zhCN" then
|
|||
|
MSG_OUTDATED = "你的 %s %s 版本已经过期 (最新版本是 %s)。你可以从 http://www.tukui.org 下载最新版本"
|
|||
|
HDR_INFORMATION = "LibElvUIPlugin-1.0.%d - 载入的插件 (绿色表示拥有当前版本, 红色表示版本已经过期)"
|
|||
|
INFO_BY = "作者"
|
|||
|
INFO_VERSION = "版本:"
|
|||
|
INFO_NEW = "最新:"
|
|||
|
LIBRARY = "库"
|
|||
|
elseif locale == "zhTW" then
|
|||
|
MSG_OUTDATED = "你的 %s %s 版本已經過期 (最新版本為 %s)。你可以透過 http://www.tukui.org 下載最新的版本"
|
|||
|
HDR_INFORMATION = "LibElvUIPlugin-1.0.%d - 載入的插件 (綠色表示擁有當前版本, 紅色表示版本已經過期)"
|
|||
|
INFO_BY = "作者"
|
|||
|
INFO_VERSION = "版本:"
|
|||
|
INFO_NEW = "最新:"
|
|||
|
LIBRARY = "庫"
|
|||
|
end
|
|||
|
|
|||
|
local E, L
|
|||
|
local function checkElvUI()
|
|||
|
if not E then
|
|||
|
if ElvUI then
|
|||
|
E = ElvUI[1]
|
|||
|
L = ElvUI[2]
|
|||
|
end
|
|||
|
|
|||
|
assert(E, "ElvUI not found.")
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
function lib:RegisterPlugin(name, callback, isLib, libVersion)
|
|||
|
checkElvUI()
|
|||
|
|
|||
|
local plugin = {
|
|||
|
name = name,
|
|||
|
callback = callback,
|
|||
|
title = GetAddOnMetadata(name, "Title"),
|
|||
|
author = GetAddOnMetadata(name, "Author")
|
|||
|
}
|
|||
|
|
|||
|
if isLib then
|
|||
|
plugin.isLib = true
|
|||
|
plugin.version = libVersion or 1
|
|||
|
else
|
|||
|
plugin.version = (name == MAJOR and MINOR) or GetAddOnMetadata(name, "Version") or UNKNOWN
|
|||
|
end
|
|||
|
|
|||
|
lib.plugins[name] = plugin
|
|||
|
|
|||
|
if not lib.registeredPrefix then
|
|||
|
C_ChatInfo_RegisterAddonMessagePrefix(lib.prefix)
|
|||
|
lib.VCFrame:RegisterEvent("CHAT_MSG_ADDON")
|
|||
|
lib.VCFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
|
|||
|
lib.VCFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|||
|
lib.registeredPrefix = true
|
|||
|
end
|
|||
|
|
|||
|
local loaded = IsAddOnLoaded("ElvUI_OptionsUI")
|
|||
|
if not loaded then
|
|||
|
lib.CFFrame:RegisterEvent("ADDON_LOADED")
|
|||
|
elseif loaded then
|
|||
|
if name ~= MAJOR then
|
|||
|
E.Options.args.plugins.args.plugins.name = lib:GeneratePluginList()
|
|||
|
end
|
|||
|
|
|||
|
if callback then
|
|||
|
callback()
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
return plugin
|
|||
|
end
|
|||
|
|
|||
|
local function SendVersionCheckMessage()
|
|||
|
lib:SendPluginVersionCheck(lib:GenerateVersionCheckMessage())
|
|||
|
end
|
|||
|
|
|||
|
function lib:DelayedSendVersionCheck(delay)
|
|||
|
if not E.SendPluginVersionCheck then
|
|||
|
E.SendPluginVersionCheck = SendVersionCheckMessage
|
|||
|
end
|
|||
|
|
|||
|
if not lib.SendMessageWaiting then
|
|||
|
lib.SendMessageWaiting = E:Delay(delay or 10, E.SendPluginVersionCheck)
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
function lib:OptionsUILoaded(_, addon)
|
|||
|
if addon == "ElvUI_OptionsUI" then
|
|||
|
lib:GetPluginOptions()
|
|||
|
|
|||
|
for _, plugin in pairs(lib.plugins) do
|
|||
|
if plugin.callback then
|
|||
|
plugin.callback()
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
lib.CFFrame:UnregisterEvent("ADDON_LOADED")
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
function lib:GenerateVersionCheckMessage()
|
|||
|
local list = ""
|
|||
|
for _, plugin in pairs(lib.plugins) do
|
|||
|
if plugin.name ~= MAJOR then
|
|||
|
list = list .. plugin.name .. "=" .. plugin.version .. ";"
|
|||
|
end
|
|||
|
end
|
|||
|
return list
|
|||
|
end
|
|||
|
|
|||
|
function lib:GetPluginOptions()
|
|||
|
E.Options.args.plugins = {
|
|||
|
order = 3,
|
|||
|
type = "group",
|
|||
|
name = L["Plugins"],
|
|||
|
inline = false,
|
|||
|
args = {
|
|||
|
pluginheader = E.Libs.ACH:Header(format(HDR_INFORMATION, MINOR), 1),
|
|||
|
plugins = {
|
|||
|
order = 2,
|
|||
|
type = "description",
|
|||
|
name = lib:GeneratePluginList()
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
end
|
|||
|
|
|||
|
do -- this will handle `8.1.5.0015` into `8.150015` etc
|
|||
|
local verStrip = function(a, b) return a..gsub(b,'%.', '') end
|
|||
|
function lib:StripVersion(version)
|
|||
|
local ver = gsub(version, '(%d-%.)([%d%.]+)', verStrip)
|
|||
|
return tonumber(ver)
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
function lib:VersionCheck(event, prefix, message, _, sender)
|
|||
|
if (event == "CHAT_MSG_ADDON" and prefix == lib.prefix) and (sender and message and not strmatch(message, "^%s-$")) then
|
|||
|
if not lib.myName then lib.myName = format('%s-%s', E.myname, E:ShortenRealm(E.myrealm)) end
|
|||
|
if sender == lib.myName then return end
|
|||
|
|
|||
|
if not E.pluginRecievedOutOfDateMessage then
|
|||
|
for name, version in gmatch(message, "([^=]+)=([%d%p]+);") do
|
|||
|
local plugin = (version and name) and lib.plugins[name]
|
|||
|
if plugin and plugin.version then
|
|||
|
local Pver, ver = lib:StripVersion(plugin.version), lib:StripVersion(version)
|
|||
|
if (ver and Pver) and (ver > Pver) then
|
|||
|
plugin.old, plugin.newversion = true, version
|
|||
|
E:Print(format(MSG_OUTDATED, plugin.title or plugin.name, plugin.version, plugin.newversion))
|
|||
|
E.pluginRecievedOutOfDateMessage = true
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
elseif event == "GROUP_ROSTER_UPDATE" then
|
|||
|
local num = GetNumGroupMembers()
|
|||
|
if num ~= lib.groupSize then
|
|||
|
if num > 1 and num > lib.groupSize then
|
|||
|
lib:DelayedSendVersionCheck()
|
|||
|
end
|
|||
|
lib.groupSize = num
|
|||
|
end
|
|||
|
elseif event == "PLAYER_ENTERING_WORLD" then
|
|||
|
lib:DelayedSendVersionCheck()
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
function lib:GeneratePluginList()
|
|||
|
local list = ""
|
|||
|
for _, plugin in pairs(lib.plugins) do
|
|||
|
if plugin.name ~= MAJOR then
|
|||
|
local color = (plugin.old and E:RGBToHex(1, 0, 0)) or E:RGBToHex(0, 1, 0)
|
|||
|
list = list .. (plugin.title or plugin.name)
|
|||
|
if plugin.author then list = list .. " " .. INFO_BY .. " " .. plugin.author end
|
|||
|
list = list .. color .. (plugin.isLib and " " .. LIBRARY or " - " .. INFO_VERSION .. " " .. plugin.version)
|
|||
|
if plugin.old then list = list .. " (" .. INFO_NEW .. plugin.newversion .. ")" end
|
|||
|
list = list .. "|r\n"
|
|||
|
end
|
|||
|
end
|
|||
|
return list
|
|||
|
end
|
|||
|
|
|||
|
function lib:ClearSendMessageWait()
|
|||
|
lib.SendMessageWaiting = nil
|
|||
|
end
|
|||
|
|
|||
|
function lib:SendPluginVersionCheck(message)
|
|||
|
if (not message) or strmatch(message, "^%s-$") then
|
|||
|
lib.ClearSendMessageWait()
|
|||
|
return
|
|||
|
end
|
|||
|
|
|||
|
local ChatType
|
|||
|
if IsInRaid() then
|
|||
|
ChatType = (not IsInRaid(LE_PARTY_CATEGORY_HOME) and IsInRaid(LE_PARTY_CATEGORY_INSTANCE)) and "INSTANCE_CHAT" or "RAID"
|
|||
|
elseif IsInGroup() then
|
|||
|
ChatType = (not IsInGroup(LE_PARTY_CATEGORY_HOME) and IsInGroup(LE_PARTY_CATEGORY_INSTANCE)) and "INSTANCE_CHAT" or "PARTY"
|
|||
|
elseif IsInGuild() then
|
|||
|
ChatType = "GUILD"
|
|||
|
end
|
|||
|
|
|||
|
if not ChatType then
|
|||
|
lib.ClearSendMessageWait()
|
|||
|
return
|
|||
|
end
|
|||
|
|
|||
|
local delay, maxChar, msgLength = 0, 250, strlen(message)
|
|||
|
if msgLength > maxChar then
|
|||
|
local splitMessage
|
|||
|
for _ = 1, ceil(msgLength / maxChar) do
|
|||
|
splitMessage = strmatch(strsub(message, 1, maxChar), ".+;")
|
|||
|
if splitMessage then -- incase the string is over 250 but doesnt contain `;`
|
|||
|
message = gsub(message, "^" .. E:EscapeString(splitMessage), "")
|
|||
|
E:Delay(delay, C_ChatInfo_SendAddonMessage, lib.prefix, splitMessage, ChatType)
|
|||
|
delay = delay + 1
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
E:Delay(delay, lib.ClearSendMessageWait)
|
|||
|
else
|
|||
|
C_ChatInfo_SendAddonMessage(lib.prefix, message, ChatType)
|
|||
|
lib.ClearSendMessageWait()
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
function lib.Initialized()
|
|||
|
if not lib.inits then return end
|
|||
|
|
|||
|
for _, initTbl in ipairs(lib.inits) do
|
|||
|
initTbl[2](initTbl[1])
|
|||
|
end
|
|||
|
|
|||
|
wipe(lib.inits)
|
|||
|
end
|
|||
|
|
|||
|
function lib:HookInitialize(tbl, func)
|
|||
|
if not (tbl and func) then return end
|
|||
|
|
|||
|
if type(func) == "string" then
|
|||
|
func = tbl[func]
|
|||
|
end
|
|||
|
|
|||
|
if not self.inits then
|
|||
|
self.inits = {}
|
|||
|
checkElvUI()
|
|||
|
hooksecurefunc(E, "Initialize", self.Initialized)
|
|||
|
end
|
|||
|
|
|||
|
tinsert(lib.inits, { tbl, func })
|
|||
|
end
|
|||
|
|
|||
|
lib.VCFrame = CreateFrame("Frame")
|
|||
|
lib.VCFrame:SetScript("OnEvent", lib.VersionCheck)
|
|||
|
|
|||
|
lib.CFFrame = CreateFrame("Frame")
|
|||
|
lib.CFFrame:SetScript("OnEvent", lib.OptionsUILoaded)
|