Quantcast

-Implementing my own hooks and trying to add gold summary

Xruptor [01-15-11 - 17:47]
-Implementing my own hooks and trying to add gold summary
Filename
libs/AceHook-3.0/AceHook-3.0.lua
libs/AceHook-3.0/AceHook-3.0.xml
libs/LibStub/LibStub.lua
libs/LibStub/LibStub.toc
xanAutoMail.lua
xanAutoMail.toc
diff --git a/libs/AceHook-3.0/AceHook-3.0.lua b/libs/AceHook-3.0/AceHook-3.0.lua
deleted file mode 100644
index 38b03dc..0000000
--- a/libs/AceHook-3.0/AceHook-3.0.lua
+++ /dev/null
@@ -1,514 +0,0 @@
---- **AceHook-3.0** offers safe Hooking/Unhooking of functions, methods and frame scripts.
--- Using AceHook-3.0 is recommended when you need to unhook your hooks again, so the hook chain isn't broken
--- when you manually restore the original function.
---
--- **AceHook-3.0** can be embeded into your addon, either explicitly by calling AceHook:Embed(MyAddon) or by
--- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
--- and can be accessed directly, without having to explicitly call AceHook itself.\\
--- It is recommended to embed AceHook, otherwise you'll have to specify a custom `self` on all calls you
--- make into AceHook.
--- @class file
--- @name AceHook-3.0
--- @release $Id: AceHook-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $
-local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 5
-local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR)
-
-if not AceHook then return end -- No upgrade needed
-
-AceHook.embeded = AceHook.embeded or {}
-AceHook.registry = AceHook.registry or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end })
-AceHook.handlers = AceHook.handlers or {}
-AceHook.actives = AceHook.actives or {}
-AceHook.scripts = AceHook.scripts or {}
-AceHook.onceSecure = AceHook.onceSecure or {}
-AceHook.hooks = AceHook.hooks or {}
-
--- local upvalues
-local registry = AceHook.registry
-local handlers = AceHook.handlers
-local actives = AceHook.actives
-local scripts = AceHook.scripts
-local onceSecure = AceHook.onceSecure
-
--- Lua APIs
-local pairs, next, type = pairs, next, type
-local format = string.format
-local assert, error = assert, error
-
--- WoW APIs
-local issecurevariable, hooksecurefunc = issecurevariable, hooksecurefunc
-local _G = _G
-
--- functions for later definition
-local donothing, createHook, hook
-
-local protectedScripts = {
-	OnClick = true,
-}
-
--- upgrading of embeded is done at the bottom of the file
-
-local mixins = {
-	"Hook", "SecureHook",
-	"HookScript", "SecureHookScript",
-	"Unhook", "UnhookAll",
-	"IsHooked",
-	"RawHook", "RawHookScript"
-}
-
--- AceHook:Embed( target )
--- target (object) - target object to embed AceHook in
---
--- Embeds AceEevent into the target object making the functions from the mixins list available on target:..
-function AceHook:Embed( target )
-	for k, v in pairs( mixins ) do
-		target[v] = self[v]
-	end
-	self.embeded[target] = true
-	-- inject the hooks table safely
-	target.hooks = target.hooks or {}
-	return target
-end
-
--- AceHook:OnEmbedDisable( target )
--- target (object) - target object that is being disabled
---
--- Unhooks all hooks when the target disables.
--- this method should be called by the target manually or by an addon framework
-function AceHook:OnEmbedDisable( target )
-	target:UnhookAll()
-end
-
-function createHook(self, handler, orig, secure, failsafe)
-	local uid
-	local method = type(handler) == "string"
-	if failsafe and not secure then
-		-- failsafe hook creation
-		uid = function(...)
-			if actives[uid] then
-				if method then
-					self[handler](self, ...)
-				else
-					handler(...)
-				end
-			end
-			return orig(...)
-		end
-		-- /failsafe hook
-	else
-		-- all other hooks
-		uid = function(...)
-			if actives[uid] then
-				if method then
-					return self[handler](self, ...)
-				else
-					return handler(...)
-				end
-			elseif not secure then -- backup on non secure
-				return orig(...)
-			end
-		end
-		-- /hook
-	end
-	return uid
-end
-
-function donothing() end
-
-function hook(self, obj, method, handler, script, secure, raw, forceSecure, usage)
-	if not handler then handler = method end
-
-	-- These asserts make sure AceHooks's devs play by the rules.
-	assert(not script or type(script) == "boolean")
-	assert(not secure or type(secure) == "boolean")
-	assert(not raw or type(raw) == "boolean")
-	assert(not forceSecure or type(forceSecure) == "boolean")
-	assert(usage)
-
-	-- Error checking Battery!
-	if obj and type(obj) ~= "table" then
-		error(format("%s: 'object' - nil or table expected got %s", usage, type(obj)), 3)
-	end
-	if type(method) ~= "string" then
-		error(format("%s: 'method' - string expected got %s", usage, type(method)), 3)
-	end
-	if type(handler) ~= "string" and type(handler) ~= "function" then
-		error(format("%s: 'handler' - nil, string, or function expected got %s", usage, type(handler)), 3)
-	end
-	if type(handler) == "string" and type(self[handler]) ~= "function" then
-		error(format("%s: 'handler' - Handler specified does not exist at self[handler]", usage), 3)
-	end
-	if script then
-	 	if not secure and obj:IsProtected() and protectedScripts[method] then
-			error(format("Cannot hook secure script %q; Use SecureHookScript(obj, method, [handler]) instead.", method), 3)
-		end
-		if not obj or not obj.GetScript or not obj:HasScript(method) then
-			error(format("%s: You can only hook a script on a frame object", usage), 3)
-		end
-	else
-		local issecure
-		if obj then
-			issecure = onceSecure[obj] and onceSecure[obj][method] or issecurevariable(obj, method)
-		else
-			issecure = onceSecure[method] or issecurevariable(method)
-		end
-		if issecure then
-			if forceSecure then
-				if obj then
-					onceSecure[obj] = onceSecure[obj] or {}
-					onceSecure[obj][method] = true
-				else
-					onceSecure[method] = true
-				end
-			elseif not secure then
-				error(format("%s: Attempt to hook secure function %s. Use `SecureHook' or add `true' to the argument list to override.", usage, method), 3)
-			end
-		end
-	end
-
-	local uid
-	if obj then
-		uid = registry[self][obj] and registry[self][obj][method]
-	else
-		uid = registry[self][method]
-	end
-
-	if uid then
-		if actives[uid] then
-			-- Only two sane choices exist here.  We either a) error 100% of the time or b) always unhook and then hook
-			-- choice b would likely lead to odd debuging conditions or other mysteries so we're going with a.
-			error(format("Attempting to rehook already active hook %s.", method))
-		end
-
-		if handlers[uid] == handler then -- turn on a decative hook, note enclosures break this ability, small memory leak
-			actives[uid] = true
-			return
-		elseif obj then -- is there any reason not to call unhook instead of doing the following several lines?
-			if self.hooks and self.hooks[obj] then
-				self.hooks[obj][method] = nil
-			end
-			registry[self][obj][method] = nil
-		else
-			if self.hooks then
-				self.hooks[method] = nil
-			end
-			registry[self][method] = nil
-		end
-		handlers[uid], actives[uid], scripts[uid] = nil, nil, nil
-		uid = nil
-	end
-
-	local orig
-	if script then
-		orig = obj:GetScript(method) or donothing
-	elseif obj then
-		orig = obj[method]
-	else
-		orig = _G[method]
-	end
-
-	if not orig then
-		error(format("%s: Attempting to hook a non existing target", usage), 3)
-	end
-
-	uid = createHook(self, handler, orig, secure, not (raw or secure))
-
-	if obj then
-		self.hooks[obj] = self.hooks[obj] or {}
-		registry[self][obj] = registry[self][obj] or {}
-		registry[self][obj][method] = uid
-
-		if not secure then
-			self.hooks[obj][method] = orig
-		end
-
-		if script then
-			-- If the script is empty before, HookScript will not work, so use SetScript instead
-			-- This will make the hook insecure, but shouldnt matter, since it was empty before.
-			-- It does not taint the full frame.
-			if not secure or orig == donothing then
-				obj:SetScript(method, uid)
-			elseif secure then
-				obj:HookScript(method, uid)
-			end
-		else
-			if not secure then
-				obj[method] = uid
-			else
-				hooksecurefunc(obj, method, uid)
-			end
-		end
-	else
-		registry[self][method] = uid
-
-		if not secure then
-			_G[method] = uid
-			self.hooks[method] = orig
-		else
-			hooksecurefunc(method, uid)
-		end
-	end
-
-	actives[uid], handlers[uid], scripts[uid] = true, handler, script and true or nil
-end
-
---- Hook a function or a method on an object.
--- The hook created will be a "safe hook", that means that your handler will be called
--- before the hooked function ("Pre-Hook"), and you don't have to call the original function yourself,
--- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
--- This type of hook is typically used if you need to know if some function got called, and don't want to modify it.
--- @paramsig [object], method, [handler], [hookSecure]
--- @param object The object to hook a method from
--- @param method If object was specified, the name of the method, or the name of the function to hook.
--- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
--- @param hookSecure If true, AceHook will allow hooking of secure functions.
--- @usage
--- -- create an addon with AceHook embeded
--- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
---
--- function MyAddon:OnEnable()
---   -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
---   self:Hook("ActionButton_UpdateHotkeys", true)
--- end
---
--- function MyAddon:ActionButton_UpdateHotkeys(button, type)
---   print(button:GetName() .. " is updating its HotKey")
--- end
-function AceHook:Hook(object, method, handler, hookSecure)
-	if type(object) == "string" then
-		method, handler, hookSecure, object = object, method, handler, nil
-	end
-
-	if handler == true then
-		handler, hookSecure = nil, true
-	end
-
-	hook(self, object, method, handler, false, false, false, hookSecure or false, "Usage: Hook([object], method, [handler], [hookSecure])")
-end
-
---- RawHook a function or a method on an object.
--- The hook created will be a "raw hook", that means that your handler will completly replace
--- the original function, and your handler has to call the original function (or not, depending on your intentions).\\
--- The original function will be stored in `self.hooks[object][method]` or `self.hooks[functionName]` respectively.\\
--- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
--- or want to control execution of the original function.
--- @paramsig [object], method, [handler], [hookSecure]
--- @param object The object to hook a method from
--- @param method If object was specified, the name of the method, or the name of the function to hook.
--- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
--- @param hookSecure If true, AceHook will allow hooking of secure functions.
--- @usage
--- -- create an addon with AceHook embeded
--- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
---
--- function MyAddon:OnEnable()
---   -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
---   self:RawHook("ActionButton_UpdateHotkeys", true)
--- end
---
--- function MyAddon:ActionButton_UpdateHotkeys(button, type)
---   if button:GetName() == "MyButton" then
---     -- do stuff here
---   else
---     self.hooks.ActionButton_UpdateHotkeys(button, type)
---   end
--- end
-function AceHook:RawHook(object, method, handler, hookSecure)
-	if type(object) == "string" then
-		method, handler, hookSecure, object = object, method, handler, nil
-	end
-
-	if handler == true then
-		handler, hookSecure = nil, true
-	end
-
-	hook(self, object, method, handler, false, false, true, hookSecure or false,  "Usage: RawHook([object], method, [handler], [hookSecure])")
-end
-
---- SecureHook a function or a method on an object.
--- This function is a wrapper around the `hooksecurefunc` function in the WoW API. Using AceHook
--- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
--- required anymore, or the addon is being disabled.\\
--- Secure Hooks should be used if the secure-status of the function is vital to its function,
--- and taint would block execution. Secure Hooks are always called after the original function was called
--- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
--- @paramsig [object], method, [handler]
--- @param object The object to hook a method from
--- @param method If object was specified, the name of the method, or the name of the function to hook.
--- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
-function AceHook:SecureHook(object, method, handler)
-	if type(object) == "string" then
-		method, handler, object = object, method, nil
-	end
-
-	hook(self, object, method, handler, false, true, false, false,  "Usage: SecureHook([object], method, [handler])")
-end
-
---- Hook a script handler on a frame.
--- The hook created will be a "safe hook", that means that your handler will be called
--- before the hooked script ("Pre-Hook"), and you don't have to call the original function yourself,
--- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
--- This is the frame script equivalent of the :Hook safe-hook. It would typically be used to be notified
--- when a certain event happens to a frame.
--- @paramsig frame, script, [handler]
--- @param frame The Frame to hook the script on
--- @param script The script to hook
--- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
--- @usage
--- -- create an addon with AceHook embeded
--- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
---
--- function MyAddon:OnEnable()
---   -- Hook the OnShow of FriendsFrame
---   self:HookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
--- end
---
--- function MyAddon:FriendsFrameOnShow(frame)
---   print("The FriendsFrame was shown!")
--- end
-function AceHook:HookScript(frame, script, handler)
-	hook(self, frame, script, handler, true, false, false, false,  "Usage: HookScript(object, method, [handler])")
-end
-
---- RawHook a script handler on a frame.
--- The hook created will be a "raw hook", that means that your handler will completly replace
--- the original script, and your handler has to call the original script (or not, depending on your intentions).\\
--- The original script will be stored in `self.hooks[frame][script]`.\\
--- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
--- or want to control execution of the original script.
--- @paramsig frame, script, [handler]
--- @param frame The Frame to hook the script on
--- @param script The script to hook
--- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
--- @usage
--- -- create an addon with AceHook embeded
--- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
---
--- function MyAddon:OnEnable()
---   -- Hook the OnShow of FriendsFrame
---   self:RawHookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
--- end
---
--- function MyAddon:FriendsFrameOnShow(frame)
---   -- Call the original function
---   self.hooks[frame].OnShow(frame)
---   -- Do our processing
---   -- .. stuff
--- end
-function AceHook:RawHookScript(frame, script, handler)
-	hook(self, frame, script, handler, true, false, true, false, "Usage: RawHookScript(object, method, [handler])")
-end
-
---- SecureHook a script handler on a frame.
--- This function is a wrapper around the `frame:HookScript` function in the WoW API. Using AceHook
--- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
--- required anymore, or the addon is being disabled.\\
--- Secure Hooks should be used if the secure-status of the function is vital to its function,
--- and taint would block execution. Secure Hooks are always called after the original function was called
--- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
--- @paramsig frame, script, [handler]
--- @param frame The Frame to hook the script on
--- @param script The script to hook
--- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
-function AceHook:SecureHookScript(frame, script, handler)
-	hook(self, frame, script, handler, true, true, false, false, "Usage: SecureHookScript(object, method, [handler])")
-end
-
---- Unhook from the specified function, method or script.
--- @paramsig [obj], method
--- @param obj The object or frame to unhook from
--- @param method The name of the method, function or script to unhook from.
-function AceHook:Unhook(obj, method)
-	local usage = "Usage: Unhook([obj], method)"
-	if type(obj) == "string" then
-		method, obj = obj, nil
-	end
-
-	if obj and type(obj) ~= "table" then
-		error(format("%s: 'obj' - expecting nil or table got %s", usage, type(obj)), 2)
-	end
-	if type(method) ~= "string" then
-		error(format("%s: 'method' - expeting string got %s", usage, type(method)), 2)
-	end
-
-	local uid
-	if obj then
-		uid = registry[self][obj] and registry[self][obj][method]
-	else
-		uid = registry[self][method]
-	end
-
-	if not uid or not actives[uid] then
-		-- Declining to error on an unneeded unhook since the end effect is the same and this would just be annoying.
-		return false
-	end
-
-	actives[uid], handlers[uid] = nil, nil
-
-	if obj then
-		registry[self][obj][method] = nil
-		registry[self][obj] = next(registry[self][obj]) and registry[self][obj] or nil
-
-		-- if the hook reference doesnt exist, then its a secure hook, just bail out and dont do any unhooking
-		if not self.hooks[obj] or not self.hooks[obj][method] then return true end
-
-		if scripts[uid] and obj:GetScript(method) == uid then  -- unhooks scripts
-			obj:SetScript(method, self.hooks[obj][method] ~= donothing and self.hooks[obj][method] or nil)
-			scripts[uid] = nil
-		elseif obj and self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then -- unhooks methods
-			obj[method] = self.hooks[obj][method]
-		end
-
-		self.hooks[obj][method] = nil
-		self.hooks[obj] = next(self.hooks[obj]) and self.hooks[obj] or nil
-	else
-		registry[self][method] = nil
-
-		-- if self.hooks[method] doesn't exist, then this is a SecureHook, just bail out
-		if not self.hooks[method] then return true end
-
-		if self.hooks[method] and _G[method] == uid then -- unhooks functions
-			_G[method] = self.hooks[method]
-		end
-
-		self.hooks[method] = nil
-	end
-	return true
-end
-
---- Unhook all existing hooks for this addon.
-function AceHook:UnhookAll()
-	for key, value in pairs(registry[self]) do
-		if type(key) == "table" then
-			for method in pairs(value) do
-				self:Unhook(key, method)
-			end
-		else
-			self:Unhook(key)
-		end
-	end
-end
-
---- Check if the specific function, method or script is already hooked.
--- @paramsig [obj], method
--- @param obj The object or frame to unhook from
--- @param method The name of the method, function or script to unhook from.
-function AceHook:IsHooked(obj, method)
-	-- we don't check if registry[self] exists, this is done by evil magicks in the metatable
-	if type(obj) == "string" then
-		if registry[self][obj] and actives[registry[self][obj]] then
-			return true, handlers[registry[self][obj]]
-		end
-	else
-		if registry[self][obj] and registry[self][obj][method] and actives[registry[self][obj][method]] then
-			return true, handlers[registry[self][obj][method]]
-		end
-	end
-
-	return false, nil
-end
-
---- Upgrade our old embeded
-for target, v in pairs( AceHook.embeded ) do
-	AceHook:Embed( target )
-end
diff --git a/libs/AceHook-3.0/AceHook-3.0.xml b/libs/AceHook-3.0/AceHook-3.0.xml
deleted file mode 100644
index a63e072..0000000
--- a/libs/AceHook-3.0/AceHook-3.0.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
-..\FrameXML\UI.xsd">
-	<Script file="AceHook-3.0.lua"/>
-</Ui>
\ No newline at end of file
diff --git a/libs/LibStub/LibStub.lua b/libs/LibStub/LibStub.lua
deleted file mode 100644
index cfc97de..0000000
--- a/libs/LibStub/LibStub.lua
+++ /dev/null
@@ -1,30 +0,0 @@
--- LibStub is a simple versioning stub meant for use in Libraries.  http://www.wowace.com/wiki/LibStub for more info
--- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
-local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2  -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
-local LibStub = _G[LIBSTUB_MAJOR]
-
-if not LibStub or LibStub.minor < LIBSTUB_MINOR then
-	LibStub = LibStub or {libs = {}, minors = {} }
-	_G[LIBSTUB_MAJOR] = LibStub
-	LibStub.minor = LIBSTUB_MINOR
-
-	function LibStub:NewLibrary(major, minor)
-		assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
-		minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
-
-		local oldminor = self.minors[major]
-		if oldminor and oldminor >= minor then return nil end
-		self.minors[major], self.libs[major] = minor, self.libs[major] or {}
-		return self.libs[major], oldminor
-	end
-
-	function LibStub:GetLibrary(major, silent)
-		if not self.libs[major] and not silent then
-			error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
-		end
-		return self.libs[major], self.minors[major]
-	end
-
-	function LibStub:IterateLibraries() return pairs(self.libs) end
-	setmetatable(LibStub, { __call = LibStub.GetLibrary })
-end
diff --git a/libs/LibStub/LibStub.toc b/libs/LibStub/LibStub.toc
deleted file mode 100644
index b43e20c..0000000
--- a/libs/LibStub/LibStub.toc
+++ /dev/null
@@ -1,13 +0,0 @@
-## Interface: 20400
-## Title: Lib: LibStub
-## Notes: Universal Library Stub
-## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
-## X-Website: http://jira.wowace.com/browse/LS
-## X-Category: Library
-## X-License: Public Domain
-## X-Curse-Packaged-Version: 1.0
-## X-Curse-Project-Name: LibStub
-## X-Curse-Project-ID: libstub
-## X-Curse-Repository-ID: wow/libstub/mainline
-
-LibStub.lua
diff --git a/xanAutoMail.lua b/xanAutoMail.lua
index 28163f9..7092bd2 100644
--- a/xanAutoMail.lua
+++ b/xanAutoMail.lua
@@ -18,8 +18,98 @@ local skipCount = 0
 local xanAutoMail = CreateFrame("frame","xanAutoMailFrame",UIParent)
 xanAutoMail:SetScript("OnEvent", function(self, event, ...) if self[event] then return self[event](self, event, ...) end end)

---lets embed AceHooks into our addon
-xanAutoMail = LibStub("AceHook-3.0"):Embed(xanAutoMail)
+--[[------------------------
+	HOOKING
+--------------------------]]
+
+local origHook = {}
+
+--create our own hooking function :)
+local function createHook(self, func, method, handler, secure, script)
+	if not func then return end
+
+	--check if already hooked
+	local chkHook = false
+	if method and origHook[func] and origHook[func][method] then
+		chkHook = true
+	elseif not method and origHook[func] then
+		chkHook = true
+	end
+
+	--if we don't have the hook and it's not secure then create it
+	if not chkHook and not secure and not script then
+
+		--create tmp hook to replace original function
+		local tmp = function(...)
+			if origHook[func] then
+				if handler then
+					return handler(self, ...)
+				elseif method then
+					return self[method](self, ...)
+				else
+					return self[func](self, ...)
+				end
+			end
+		end
+
+		--check to see if were using a method, if we aren't then replace hook
+		if not method then
+			--store the original hook and then replace it
+			origHook[func] = _G[func]
+			_G[func] = tmp
+		else
+			origHook[func] = origHook[func] or {}
+			origHook[func][method] = _G[func][method]
+			_G[func][method] = tmp
+		end
+
+	elseif not chkHook and not secure and method and script then
+		--NOTE: func cannot be a string
+		--store the old script
+		origHook[func] = origHook[func] or {}
+		origHook[func][method] = func:GetScript(method)
+
+		if handler then
+			func:SetScript(method, handler)
+		else
+			func:SetScript(method, self[method])
+			--will use a function from the addon as follows
+			--self:method(...)
+		end
+
+	elseif not chkHook and secure then
+
+		--it's a secure hook
+		if not method then
+			--NOTE: func must be a string for this to work properly
+			if handler then
+				hooksecurefunc(func, handler)
+			else
+				hooksecurefunc(func, self[func])
+				--will use a function from the addon as follows
+				--self:func(...)
+			end
+			origHook[func] = true
+		else
+			--NOTE: func must be a function/table and cannot be a string, method must be a string
+			if handler then
+				hooksecurefunc(func, method, handler)
+			else
+				hooksecurefunc(func, method, self[method])
+				--will use a function from the addon as follows
+				--self:method(...)
+			end
+			origHook[func] = origHook[func] or {}
+			origHook[func][method] = true
+		end
+
+	end
+
+end
+
+--[[------------------------
+	CORE
+--------------------------]]

 function xanAutoMail:PLAYER_LOGIN()

@@ -33,11 +123,11 @@ function xanAutoMail:PLAYER_LOGIN()
 	SendMailNameEditBox:SetHistoryLines(15)

 	--do the hooks
-	self:RawHook("SendMailFrame_Reset", true)
-	self:RawHook("MailFrameTab_OnClick", true)
-	self:RawHookScript(SendMailNameEditBox, "OnChar")
-	self:HookScript(SendMailNameEditBox, "OnEditFocusGained")
-	self:RawHook("AutoComplete_Update", true)
+	createHook(self, "SendMailFrame_Reset")
+	createHook(self, "MailFrameTab_OnClick")
+	createHook(self, "AutoComplete_Update")
+	createHook(self, SendMailNameEditBox, "OnEditFocusGained", nil, nil, true)
+	createHook(self, SendMailNameEditBox, "OnChar", nil, nil, true)

 	--make the open all button
 	inboxAllButton = CreateFrame("Button", "xanAutoMail_OpenAllBTN", InboxFrame, "UIPanelButtonTemplate")
@@ -75,7 +165,7 @@ function xanAutoMail:SendMailFrame_Reset()

 	--if we don't have something to work with then call original function
 	if string.len(playerName) < 1 then
-		return self.hooks["SendMailFrame_Reset"]()
+		return origHook["SendMailFrame_Reset"]()
 	end

 	--add the name to the history
@@ -94,7 +184,7 @@ function xanAutoMail:SendMailFrame_Reset()
 	for k = #DB_RECENT, 11, -1 do
 		tremove(DB_RECENT, k)
 	end
-	self.hooks["SendMailFrame_Reset"]()
+	origHook["SendMailFrame_Reset"]()

 	-- set the name to the auto fill
 	SendMailNameEditBox:SetText(playerName)
@@ -103,8 +193,8 @@ end

 --this is called when one of the mailtabs is clicked
 --we have to autofill the name when the tabs are clicked
-function xanAutoMail:MailFrameTab_OnClick(button, tab)
-	self.hooks["MailFrameTab_OnClick"](button, tab)
+function xanAutoMail:MailFrameTab_OnClick(self, tab)
+	origHook["MailFrameTab_OnClick"](self, tab)
 	if tab == 2 then
 		local playerName = DB_RECENT[1]
 		if playerName and SendMailNameEditBox:GetText() == "" then
@@ -115,10 +205,10 @@ function xanAutoMail:MailFrameTab_OnClick(button, tab)
 end

 --this function is called each time a character is pressed in the playername field of the mail window
-function xanAutoMail:OnChar(editbox, ...)
-	if editbox:GetUTF8CursorPosition() ~= strlenutf8(editbox:GetText()) then return end
+function xanAutoMail:OnChar(...)

-	local text = strupper(editbox:GetText())
+	if self:GetUTF8CursorPosition() ~= strlenutf8(self:GetText()) then return end
+	local text = strupper(self:GetText())
 	local textlen = strlen(text)
 	local foundName

@@ -156,24 +246,24 @@ function xanAutoMail:OnChar(editbox, ...)
 	end

 	--call the original onChar to display the dropdown
-	self.hooks[SendMailNameEditBox].OnChar(editbox, ...)
-
+	origHook[SendMailNameEditBox]["OnChar"](self, ...)
+
 	--if we found a name then override the one in the editbox
 	if foundName then
-		editbox:SetText(foundName)
-		editbox:HighlightText(textlen, -1)
-		editbox:SetCursorPosition(textlen)
+		self:SetText(foundName)
+		self:HighlightText(textlen, -1)
+		self:SetCursorPosition(textlen)
 	end

 end

-function xanAutoMail:OnEditFocusGained(editbox, ...)
+function xanAutoMail:OnEditFocusGained(...)
 	SendMailNameEditBox:HighlightText()
 end

 function xanAutoMail:AutoComplete_Update(editBox, editBoxText, utf8Position, ...)
 	if editBox ~= SendMailNameEditBox then
-		self.hooks["AutoComplete_Update"](editBox, editBoxText, utf8Position, ...)
+		origHook["AutoComplete_Update"](editBox, editBoxText, utf8Position, ...)
 	end
 end

diff --git a/xanAutoMail.toc b/xanAutoMail.toc
index 74bdd2f..fe90ff9 100644
--- a/xanAutoMail.toc
+++ b/xanAutoMail.toc
@@ -2,7 +2,7 @@
 ## Title: xanAutoMail
 ## Notes: Expands blizzards automatic name generation for sending Mail to include people outside the guild.
 ## Author: Xruptor
-## Version: 1.4
+## Version: 1.5
 ## SavedVariables: xanAutoMailDB

 libs\LibStub\LibStub.lua