📄 stubby.lua
字号:
else local addon = string.lower(triggerAddOn) if (not config.loads[addon]) then config.loads[addon] = {} end config.loads[addon][ownerAddOn] = nil if (hookFunction) then config.loads[addon][ownerAddOn] = { f=hookFunction, a=arg } end endendfunction unregisterAddOnHook(triggerAddOn, ownerAddOn) local addon = string.lower(triggerAddOn) if (config.loads and config.loads[addon] and config.loads[addon][ownerAddOn]) then config.loads[addon][ownerAddOn] = nil endendfunction loadWatcher(loadedAddOn) local addon = string.lower(loadedAddOn) if (config.loads[addon]) then local ownerAddOn, hookDetail for ownerAddOn, hookDetail in config.loads[addon] do hookDetail.f(hookDetail.a) end endend-- This function registers a given function to be called when a given-- event is fired (this can be used to activate an addon upon receipt-- of a given event etc)function registerEventHook(triggerEvent, ownerAddOn, hookFunction, ...) if (not config.events[triggerEvent]) then config.events[triggerEvent] = {} StubbyFrame:RegisterEvent(triggerEvent) end config.events[triggerEvent][ownerAddOn] = nil if (hookFunction) then config.events[triggerEvent][ownerAddOn] = { f=hookFunction, a=arg } endendfunction unregisterEventHook(triggerEvent, ownerAddOn) if (config.events and config.events[triggerEvent] and config.events[triggerEvent][ownerAddOn]) then config.events[triggerEvent][ownerAddOn] = nil endendfunction eventWatcher(event) if (config.events[event]) then local ownerAddOn, hookDetail for ownerAddOn, hookDetail in config.events[event] do hookDetail.f(hookDetail.a, event, arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15,arg16,arg17,arg18,arg19,arg20); end endend-- This function registers boot code. This is a piece of code-- specified as a string, which Stubby will execute on your behalf-- when we are first loaded. This code can do anything a normal-- lua script can, such as create global functions, register a-- command handler, hook into functions, load your addon etc.-- Leaving bootCode nil will remove your boot.function registerBootCode(ownerAddOn, bootName, bootCode) local ownerIndex = string.lower(ownerAddOn) local bootIndex = string.lower(bootName) if (not StubbyConfig.boots) then StubbyConfig.boots = {} end if (not StubbyConfig.boots[ownerIndex]) then StubbyConfig.boots[ownerIndex] = {} end StubbyConfig.boots[ownerIndex][bootIndex] = nil if (bootCode) then StubbyConfig.boots[ownerIndex][bootIndex] = bootCode endendfunction unregisterBootCode(ownerAddOn, bootName) local ownerIndex = string.lower(ownerAddOn) local bootIndex = string.lower(bootName) if not (StubbyConfig.boots) then return end if not (ownerIndex and StubbyConfig.boots[ownerIndex]) then return end if (bootIndex == nil) then StubbyConfig.boots[ownerIndex] = nil else StubbyConfig.boots[ownerIndex][bootIndex] = nil endendfunction createAddOnLoadBootCode(ownerAddOn, triggerAddOn) registerBootCode(ownerAddOn, triggerAddOn.."AddOnLoader", 'local function hookFunction() '.. 'LoadAddOn("'..ownerAddOn..'") '.. 'Stubby.UnregisterAddOnHook("'..triggerAddOn..'", "'..ownerAddOn..'") '.. 'end '.. 'Stubby.RegisterAddOnHook("'..triggerAddOn..'", "'..ownerAddOn..'", hookFunction)' );endfunction createFunctionLoadBootCode(ownerAddOn, triggerFunction) registerBootCode(ownerAddOn, triggerFunction.."FunctionLoader", 'local function hookFunction() '.. 'LoadAddOn("'..ownerAddOn..'") '.. 'Stubby.UnregisterFunctionHook("'..triggerFunction..'", hookFunction) '.. 'end '.. 'Stubby.RegisterFunctionHook("'..triggerFunction..'", 200, hookFunction)' );endfunction createEventLoadBootCode(ownerAddOn, triggerEvent) registerBootCode(ownerAddOn, triggerEvent.."FunctionLoader", 'local function hookFunction() '.. 'LoadAddOn("'..ownerAddOn..'") '.. 'Stubby.UnregisterEventHook("'..triggerEvent..'", "'..ownerAddOn..'") '.. 'end '.. 'Stubby.RegisterEventHook("'..triggerEvent..'", "'..ownerAddOn..'", hookFunction)' );end-- Functions to check through all addons for dependants.-- If any exist that we don't know about, and have a dependancy of us, then we will load them-- once to give them a chance to register themselves with us.function checkAddOns() if not StubbyConfig.inspected then return end local goodList = {} local addonCount = GetNumAddOns() local name, title, notes for i=1, addonCount do name, title, notes = GetAddOnInfo(i) if (StubbyConfig.inspected and StubbyConfig.inspected[name]) then local infoCompare = title.."|"..(notes or "") if (infoCompare == StubbyConfig.addinfo[name]) then goodList[name] = true end end end for name,_ in StubbyConfig.inspected do if (not goodList[name]) then StubbyConfig.inspected[name] = nil StubbyConfig.addinfo[name] = nil end endend-- Cleans up boot codes for removed addons and prompts for deletion of their-- configurations.function cleanUpAddOnData() if (not StubbyConfig.boots) then return; end for b in pairs(StubbyConfig.boots) do local _,title = GetAddOnInfo(b) if (not title) then StubbyConfig.boots[b] = nil if (StubbyConfig.configs) then if (cleanList == nil) then cleanList = {}; end table.insert(cleanList, b) end end end if (cleanList) then cleanUpAddOnConfigs(); endend-- Shows confirmation dialogs to clean configuration for addons that have-- just been removed. Warning: Calls itself recursively until done.function cleanUpAddOnConfigs() if (not cleanList) then return; end local addonIndex = table.getn(cleanList) local addonName = cleanList[addonIndex] if (addonIndex == 1) then cleanList = nil else table.remove(cleanList, addonIndex) end StaticPopupDialogs["CLEANUP_STUBBY" .. addonIndex] = { text = "The AddOn \"" .. addonName .. "\" is no longer available. Do you wish to delete it's loading preferences?", button1 = "Delete", button2 = "Keep", OnAccept = function() StubbyConfig.configs[addonName] = nil cleanUpAddOnConfigs(); end, OnCancel = function() cleanUpAddOnConfigs(); end, timeout = 0, whileDead = 1, }; StaticPopup_Show("CLEANUP_STUBBY" .. addonIndex, "","");endfunction shouldInspectAddOn(addonName) if not StubbyConfig.inspected[addonName] then return true end return falseendfunction inspectAddOn(addonName, title, info) LoadAddOn(addonName) StubbyConfig.inspected[addonName] = true StubbyConfig.addinfo[addonName] = title.."|"..(info or "")endfunction searchForNewAddOns() local addonCount = GetNumAddOns() local name, title, notes, enabled, loadable, reason, security, requiresLoad for i=1, addonCount do requiresLoad = false name, title, notes, enabled, loadable, reason, security = GetAddOnInfo(i) if (IsAddOnLoadOnDemand(i) and shouldInspectAddOn(name) and loadable) then local addonDeps = { GetAddOnDependencies(i) } for _, dependancy in pairs(addonDeps) do if (string.lower(dependancy) == "stubby") then requiresLoad = true end end end if (requiresLoad) then inspectAddOn(name, title, notes) end endend-- This function runs through the boot scripts we have, and if the-- related addon is not loaded yet, runs the boot script.function runBootCodes() if (not StubbyConfig.boots) then return end for addon, boots in StubbyConfig.boots do if (not IsAddOnLoaded(addon) and IsAddOnLoadOnDemand(addon)) then local _, _, _, _, loadable = GetAddOnInfo(addon) if (loadable) then for bootname, boot in pairs(boots) do RunScript(boot) end end end endendfunction onWorldStart() -- Check for expired or updated addons and remove their boot codes. checkAddOns() -- Run all of our boots to setup the respective addons functions. runBootCodes() -- The search for new life and new civilizations... or just addons maybe. searchForNewAddOns() -- Delete data for removed addons cleanUpAddOnData()endfunction onLoaded() if not StubbyConfig.inspected then StubbyConfig.inspected = {} end if not StubbyConfig.addinfo then StubbyConfig.addinfo = {} end Stubby.RegisterEventHook("PLAYER_LOGIN", "Stubby", onWorldStart)endfunction events(event, param) if (not event) then event = "" end if (not param) then param = "" end if (event == "ADDON_LOADED") then if (string.lower(param) == "stubby") then onLoaded() end Stubby.LoadWatcher(param) end Stubby.EventWatcher(event)endfunction chatPrint(...) if ( DEFAULT_CHAT_FRAME ) then local msg = "" for i=1, table.getn(arg) do if i==1 then msg = arg[i] else msg = msg.." "..arg[i] end end DEFAULT_CHAT_FRAME:AddMessage(msg, 1.0, 0.35, 0.15) endend-- This function allows boot code to store a configuration variable-- by default the variable is per character unless isGlobal is set.function setConfig(ownerAddOn, variable, value, isGlobal) local ownerIndex = string.lower(ownerAddOn) local varIndex = string.lower(variable) if (not isGlobal) then varIndex = string.lower(UnitName("player")) .. ":" .. varIndex end if (not StubbyConfig.configs) then StubbyConfig.configs = {} end if (not StubbyConfig.configs[ownerIndex]) then StubbyConfig.configs[ownerIndex] = {} end StubbyConfig.configs[ownerIndex][varIndex] = valueend-- This function gets a config variable stored by the above function-- it will prefer a player specific variable over a global with the-- same namefunction getConfig(ownerAddOn, variable) local ownerIndex = string.lower(ownerAddOn) local globalIndex = string.lower(variable) local playerIndex = string.lower(UnitName("player")) .. ":" .. globalIndex if (not StubbyConfig.configs) then return end if (not StubbyConfig.configs[ownerIndex]) then return end local curValue = StubbyConfig.configs[ownerIndex][playerIndex] if (curValue == nil) then curValue = StubbyConfig.configs[ownerIndex][globalIndex] end return curValueend-- This function clears the config variable specified (both the-- global and player specific) or all config variables for the-- ownerAddOn if no variable is specifiedfunction clearConfig(ownerAddOn, variable) local ownerIndex = string.lower(ownerAddOn) if (not StubbyConfig.configs) then return end if (not StubbyConfig.configs[ownerIndex]) then return end if (variable) then local globalIndex = string.lower(variable) local playerIndex = string.lower(UnitName("player")) .. ":" .. globalIndex StubbyConfig.configs[ownerIndex][globalIndex] = nil StubbyConfig.configs[ownerIndex][playerIndex] = nil else StubbyConfig.configs[ownerIndex] = nil endend-- Extract the revision number from SVN keyword stringlocal function getRevision() local found, _, rev = string.find("$Revision: 803 $", "(%d+)") if (found ~= nil) then return tonumber(rev); end return nilend-- Setup our Stubby global object. All interaction is done-- via the methods exposed here.Stubby = { VERSION = getRevision(), Print = chatPrint, Events = events, HookCall = hookCall, SetConfig = setConfig, GetConfig = getConfig, ClearConfig = clearConfig, GetOrigFunc = getOrigFunc, LoadWatcher = loadWatcher, EventWatcher = eventWatcher, RegisterBootCode = registerBootCode, RegisterEventHook = registerEventHook, RegisterAddOnHook = registerAddOnHook, RegisterFunctionHook = registerFunctionHook, UnregisterBootCode = unregisterBootCode, UnregisterEventHook = unregisterEventHook, UnregisterAddOnHook = unregisterAddOnHook, UnregisterFunctionHook = unregisterFunctionHook, CreateAddOnLoadBootCode = createAddOnLoadBootCode, CreateEventLoadBootCode = createEventLoadBootCode, CreateFunctionLoadBootCode = createFunctionLoadBootCode,}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -