Fix a few edge cases and correctly error if the function doesn't exist.

This commit is contained in:
FireSiku 2018-06-08 01:54:13 -04:00
parent 722bc35f60
commit 4af4cd5f75

View file

@ -74,7 +74,7 @@ local function get_orig_function(self, obj, method)
end end
-- Return an object from the global table. Second return value is if it was sucessful. -- Return an object from the global table. Second return value is if it was sucessful.
local function get_object_from_string(obj) local function get_object_reference(obj)
if type(obj) == "table" then if type(obj) == "table" then
return obj, true return obj, true
elseif type(obj) == "string" then elseif type(obj) == "string" then
@ -239,7 +239,7 @@ end
-- self, string (method), function (handler), nil, string (func_name) -- self, string (method), function (handler), nil, string (func_name)
local function generic_hook(self, obj, method, handler, func_name) local function generic_hook(self, obj, method, handler, func_name)
if vmf.check_wrong_argument_type(self, func_name, "obj", obj, "string", "table") or if vmf.check_wrong_argument_type(self, func_name, "obj", obj, "string", "table", "nil") or
vmf.check_wrong_argument_type(self, func_name, "method", method, "string", "function") or vmf.check_wrong_argument_type(self, func_name, "method", method, "string", "function") or
vmf.check_wrong_argument_type(self, func_name, "handler", handler, "function", "nil") vmf.check_wrong_argument_type(self, func_name, "handler", handler, "function", "nil")
then then
@ -250,15 +250,19 @@ local function generic_hook(self, obj, method, handler, func_name)
if type(method) == "function" then if type(method) == "function" then
handler = method handler = method
method, obj = split_function_string(obj) method, obj = split_function_string(obj)
if not method then
self:error("(%s): trying to create hook without giving a method name. %s", func_name)
return
end
end end
-- Get hook_type based on name -- Get hook_type based on name
local hook_type = HOOK_TYPES[func_name] local hook_type = HOOK_TYPES[func_name]
-- Check if hook should be delayed. -- Grab the object's reference, if this fails, obj will remains a string and the hook will be delayed.
local obj, sucess = get_object_from_string(obj) --luacheck: ignore local obj, sucess = get_object_reference(obj) --luacheck: ignore
if not sucess then if obj and not sucess then
if _delaying_enabled then if _delaying_enabled and type(obj) == "string" then
-- Call this func at a later time, using upvalues. -- Call this func at a later time, using upvalues.
vmf:info("(%s): [%s.%s] needs to be delayed.", func_name, obj, method) vmf:info("(%s): [%s.%s] needs to be delayed.", func_name, obj, method)
table.insert(_delayed, function() table.insert(_delayed, function()
@ -271,6 +275,15 @@ local function generic_hook(self, obj, method, handler, func_name)
end end
end end
-- Quick check to make sure the target exists
if obj and not obj[method] then
self:error("(%s): trying to hook method that doesn't exist: [%s.%s]", func_name, obj, method)
return
elseif not obj and not rawget(_G, method) then
self:error("(%s): trying to hook function that doesn't exist: [%s]", func_name, method)
return
end
-- obj can't be a string for these now. -- obj can't be a string for these now.
local orig = get_orig_function(self, obj, method) local orig = get_orig_function(self, obj, method)
return create_hook(self, orig, obj, method, handler, func_name, hook_type) return create_hook(self, orig, obj, method, handler, func_name, hook_type)
@ -286,11 +299,15 @@ local function generic_hook_toggle(self, obj, method, enabled_state)
-- Adjust the arguments. -- Adjust the arguments.
if not method then if not method then
method, obj = split_function_string(obj) if type(obj) == "string" then
method, obj = split_function_string(obj)
else
self:error("(%s): trying to toggle hook without giving a method name. %s", func_name)
end
end end
local obj, sucess = get_object_from_string(obj) --luacheck: ignore local obj, sucess = get_object_reference(obj) --luacheck: ignore
if not sucess then if obj and not sucess then
self:error("(%s): object doesn't exist.", func_name) self:error("(%s): object doesn't exist.", func_name)
return return
end end
@ -375,6 +392,7 @@ end
vmf.apply_delayed_hooks = function() vmf.apply_delayed_hooks = function()
_delaying_enabled = false _delaying_enabled = false
if #_delayed > 0 then if #_delayed > 0 then
vmf:info("Attempt to hook %s delayed hooks", #_delayed)
-- Go through the table in reverse so we don't get any issues removing entries inside the loop -- Go through the table in reverse so we don't get any issues removing entries inside the loop
for i = #_delayed, 1, -1 do for i = #_delayed, 1, -1 do
_delayed[i]() _delayed[i]()