⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dongle.lua

📁 魔兽世界月光宝盒 感觉挺好
💻 LUA
📖 第 1 页 / 共 3 页
字号:
--[[-------------------------------------------------------------------------  Copyright (c) 2006-2007, Dongle Development Team  All rights reserved.  Redistribution and use in source and binary forms, with or without  modification, are permitted provided that the following conditions are  met:      * Redistributions of source code must retain the above copyright        notice, this list of conditions and the following disclaimer.      * Redistributions in binary form must reproduce the above        copyright notice, this list of conditions and the following        disclaimer in the documentation and/or other materials provided        with the distribution.      * Neither the name of the Dongle Development Team nor the names of        its contributors may be used to endorse or promote products derived        from this software without specific prior written permission.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.---------------------------------------------------------------------------]]local major = "DongleStub"local minor = tonumber(string.match("$Revision: 313 $", "(%d+)") or 1)local g = getfenv(0)if not g.DongleStub or g.DongleStub:IsNewerVersion(major, minor) then	local lib = setmetatable({}, {		__call = function(t,k) 			if type(t.versions) == "table" and t.versions[k] then 				return t.versions[k].instance			else				error("Cannot find a library with name '"..tostring(k).."'", 2)			end		end	})	function lib:IsNewerVersion(major, minor)		local versionData = self.versions and self.versions[major]		-- If DongleStub versions have differing major version names		-- such as DongleStub-Beta0 and DongleStub-1.0-RC2 then a second		-- instance will be loaded, with older logic.  This code attempts		-- to compensate for that by matching the major version against		-- "^DongleStub", and handling the version check correctly.		if major:match("^DongleStub") then			local oldmajor,oldminor = self:GetVersion()			if self.versions and self.versions[oldmajor] then				return minor > oldminor			else				return true			end		end		if not versionData then return true end		local oldmajor,oldminor = versionData.instance:GetVersion()		return minor > oldminor	end		local function NilCopyTable(src, dest)		for k,v in pairs(dest) do dest[k] = nil end		for k,v in pairs(src) do dest[k] = v end	end	function lib:Register(newInstance, activate, deactivate)		assert(type(newInstance.GetVersion) == "function",			"Attempt to register a library with DongleStub that does not have a 'GetVersion' method.")		local major,minor = newInstance:GetVersion()		assert(type(major) == "string",			"Attempt to register a library with DongleStub that does not have a proper major version.")		assert(type(minor) == "number",			"Attempt to register a library with DongleStub that does not have a proper minor version.")		-- Generate a log of all library registrations		if not self.log then self.log = {} end		table.insert(self.log, string.format("Register: %s, %s", major, minor))		if not self:IsNewerVersion(major, minor) then return false end		if not self.versions then self.versions = {} end		local versionData = self.versions[major]		if not versionData then			-- New major version			versionData = {				["instance"] = newInstance,				["deactivate"] = deactivate,			}						self.versions[major] = versionData			if type(activate) == "function" then				table.insert(self.log, string.format("Activate: %s, %s", major, minor))				activate(newInstance)			end			return newInstance		end				local oldDeactivate = versionData.deactivate		local oldInstance = versionData.instance				versionData.deactivate = deactivate				local skipCopy		if type(activate) == "function" then			table.insert(self.log, string.format("Activate: %s, %s", major, minor))			skipCopy = activate(newInstance, oldInstance)		end		-- Deactivate the old libary if necessary		if type(oldDeactivate) == "function" then			local major, minor = oldInstance:GetVersion()			table.insert(self.log, string.format("Deactivate: %s, %s", major, minor))			oldDeactivate(oldInstance, newInstance)		end		-- Re-use the old table, and discard the new one		if not skipCopy then			NilCopyTable(newInstance, oldInstance)		end		return oldInstance	end	function lib:GetVersion() return major,minor end	local function Activate(new, old)		-- This code ensures that we'll move the versions table even		-- if the major version names are different, in the case of 		-- DongleStub		if not old then old = g.DongleStub end		if old then			new.versions = old.versions			new.log = old.log		end		g.DongleStub = new	end		-- Actually trigger libary activation here	local stub = g.DongleStub or lib	lib = stub:Register(lib, Activate)end--[[-------------------------------------------------------------------------  Begin Library Implementation---------------------------------------------------------------------------]]local major = "Dongle-1.0"local minor = tonumber(string.match("$Revision: 371 $", "(%d+)") or 1) + 500-- ** IMPORTANT NOTE **-- Due to some issues we had previously with Dongle revision numbers-- we need to artificially inflate the minor revision number, to ensure-- we load sequentially.assert(DongleStub, string.format("%s requires DongleStub.", major))if not DongleStub:IsNewerVersion(major, minor) then return endlocal Dongle = {}local methods = {	"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents", "IsEventRegistered",	"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages", "TriggerMessage", "IsMessageRegistered",	"EnableDebug", "IsDebugEnabled", "Print", "PrintF", "Debug", "DebugF", "Echo", "EchoF",	"InitializeDB",	"InitializeSlashCommand",	"NewModule", "HasModule", "IterateModules",}local registry = {}local lookup = {}local loadqueue = {}local loadorder = {}local events = {}local databases = {}local commands = {}local messages = {}local frame--[[-------------------------------------------------------------------------	Message Localization---------------------------------------------------------------------------]]local L = {	["ADDMESSAGE_REQUIRED"] = "The frame you specify must have an 'AddMessage' method.",	["ALREADY_REGISTERED"] = "A Dongle with the name '%s' is already registered.",	["BAD_ARGUMENT"] = "bad argument #%d to '%s' (%s expected, got %s)",	["BAD_ARGUMENT_DB"] = "bad argument #%d to '%s' (DongleDB expected)",	["CANNOT_DELETE_ACTIVE_PROFILE"] = "You cannot delete your active profile. Change profiles, then attempt to delete.",	["DELETE_NONEXISTANT_PROFILE"] = "You cannot delete a non-existant profile.",	["MUST_CALLFROM_DBOBJECT"] = "You must call '%s' from a Dongle database object.",	["MUST_CALLFROM_REGISTERED"] = "You must call '%s' from a registered Dongle.",	["MUST_CALLFROM_SLASH"] = "You must call '%s' from a Dongle slash command object.",	["PROFILE_DOES_NOT_EXIST"] = "Profile '%s' doesn't exist.",	["REPLACE_DEFAULTS"] = "You are attempting to register defaults with a database that already contains defaults.",	["SAME_SOURCE_DEST"] = "Source/Destination profile cannot be the same profile.",	["EVENT_REGISTER_SPECIAL"] = "You cannot register for the '%s' event. Use the '%s' method instead.",	["Unknown"] = "Unknown",	["INJECTDB_USAGE"] = "Usage: DongleCmd:InjectDBCommands(db, ['copy', 'delete', 'list', 'reset', 'set'])",	["DBSLASH_PROFILE_COPY_DESC"] = "profile copy <name> - Copies profile <name> into your current profile.",	["DBSLASH_PROFILE_COPY_PATTERN"] = "^profile copy (.+)$",	["DBSLASH_PROFILE_DELETE_DESC"] = "profile delete <name> - Deletes the profile <name>.",	["DBSLASH_PROFILE_DELETE_PATTERN"] = "^profile delete (.+)$",	["DBSLASH_PROFILE_LIST_DESC"] = "profile list - Lists all valid profiles.",	["DBSLASH_PROFILE_LIST_PATTERN"] = "^profile list$",	["DBSLASH_PROFILE_RESET_DESC"] = "profile reset - Resets the current profile.",	["DBSLASH_PROFILE_RESET_PATTERN"] = "^profile reset$",	["DBSLASH_PROFILE_SET_DESC"] = "profile set <name> - Sets the current profile to <name>.",	["DBSLASH_PROFILE_SET_PATTERN"] = "^profile set (.+)$",	["DBSLASH_PROFILE_LIST_OUT"] = "Profile List:",}--[[-------------------------------------------------------------------------	Utility functions for Dongle use---------------------------------------------------------------------------]]local function assert(level,condition,message)	if not condition then		error(message,level)	endendlocal function argcheck(value, num, ...)	if type(num) ~= "number" then		error(L["BAD_ARGUMENT"]:format(2, "argcheck", "number", type(num)), 1)	end	for i=1,select("#", ...) do		if type(value) == select(i, ...) then return end	end	local types = strjoin(", ", ...)	local name = string.match(debugstack(2,2,0), ": in function [`<](.-)['>]")	error(L["BAD_ARGUMENT"]:format(num, name, types, type(value)), 3)endlocal function safecall(func,...)	local success,err = pcall(func,...)	if not success then		geterrorhandler()(err)	endend--[[-------------------------------------------------------------------------	Dongle constructor, and DongleModule system---------------------------------------------------------------------------]]function Dongle:New(name, obj)	argcheck(name, 2, "string")	argcheck(obj, 3, "table", "nil")	if not obj then		obj = {}	end	if registry[name] then		error(string.format(L["ALREADY_REGISTERED"], name))	end	local reg = {["obj"] = obj, ["name"] = name}	registry[name] = reg	lookup[obj] = reg	lookup[name] = reg	for k,v in pairs(methods) do		obj[v] = self[v]	end	-- Add this Dongle to the end of the queue	table.insert(loadqueue, obj)	return obj,nameendfunction Dongle:NewModule(name, obj)	local reg = lookup[self]	assert(3, reg, string.format(L["MUST_CALLFROM_REGISTERED"], "NewModule"))	argcheck(name, 2, "string")	argcheck(obj, 3, "table", "nil")	obj,name = Dongle:New(name, obj)	if not reg.modules then reg.modules = {} end	reg.modules[obj] = obj	reg.modules[name] = obj	return obj,nameendfunction Dongle:HasModule(module)	local reg = lookup[self]	assert(3, reg, string.format(L["MUST_CALLFROM_REGISTERED"], "HasModule"))	argcheck(module, 2, "string", "table")	return reg.modules and reg.modules[module]endlocal function ModuleIterator(t, name)	if not t then return end	local obj	repeat		name,obj = next(t, name)	until type(name) == "string" or not name	return name,objendfunction Dongle:IterateModules()	local reg = lookup[self]	assert(3, reg, string.format(L["MUST_CALLFROM_REGISTERED"], "IterateModules"))	return ModuleIterator, reg.modulesend--[[-------------------------------------------------------------------------	Event registration system---------------------------------------------------------------------------]]local function OnEvent(frame, event, ...)	local eventTbl = events[event]	if eventTbl then		for obj,func in pairs(eventTbl) do			if type(func) == "string" then				if type(obj[func]) == "function" then					safecall(obj[func], obj, event, ...)				end			else				safecall(func, event, ...)			end		end	endendlocal specialEvents = {	["PLAYER_LOGIN"] = "Enable",	["PLAYER_LOGOUT"] = "Disable",}function Dongle:RegisterEvent(event, func)	local reg = lookup[self]	assert(3, reg, string.format(L["MUST_CALLFROM_REGISTERED"], "RegisterEvent"))	argcheck(event, 2, "string")	argcheck(func, 3, "string", "function", "nil")	local special = (self ~= Dongle) and specialEvents[event]	if special then		error(string.format(L["EVENT_REGISTER_SPECIAL"], event, special), 3)	end	-- Name the method the same as the event if necessary	if not func then func = event end	if not events[event] then		events[event] = {}		frame:RegisterEvent(event)	end	events[event][self] = funcendfunction Dongle:UnregisterEvent(event)	local reg = lookup[self]	assert(3, reg, string.format(L["MUST_CALLFROM_REGISTERED"], "UnregisterEvent"))	argcheck(event, 2, "string")	local tbl = events[event]	if tbl then		tbl[self] = nil		if not next(tbl) then			events[event] = nil			frame:UnregisterEvent(event)		end	endendfunction Dongle:UnregisterAllEvents()	local reg = lookup[self]	assert(3, reg, string.format(L["MUST_CALLFROM_REGISTERED"], "UnregisterAllEvents"))	for event,tbl in pairs(events) do		tbl[self] = nil		if not next(tbl) then			events[event] = nil			frame:UnregisterEvent(event)		end	endendfunction Dongle:IsEventRegistered(event)	local reg = lookup[self]	assert(3, reg, string.format(L["MUST_CALLFROM_REGISTERED"], "IsEventRegistered"))	argcheck(event, 2, "string")	local tbl = events[event]	return tblend--[[-------------------------------------------------------------------------	Inter-Addon Messaging System---------------------------------------------------------------------------]]function Dongle:RegisterMessage(msg, func)	argcheck(self, 1, "table")	argcheck(msg, 2, "string")	argcheck(func, 3, "string", "function", "nil")	-- Name the method the same as the message if necessary	if not func then func = msg end	if not messages[msg] then		messages[msg] = {}	end	messages[msg][self] = funcendfunction Dongle:UnregisterMessage(msg)	argcheck(self, 1, "table")	argcheck(msg, 2, "string")	local tbl = messages[msg]	if tbl then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -