refactor: Move indexed objects to local and change whitespace
This commit is contained in:
parent
a36e6f4adb
commit
15dc40b9ab
5 changed files with 327 additions and 302 deletions
31
.luacheckrc
31
.luacheckrc
|
@ -10,7 +10,30 @@ ignore = {
|
||||||
"212/self", -- Disable unused self warnings.
|
"212/self", -- Disable unused self warnings.
|
||||||
}
|
}
|
||||||
|
|
||||||
std = "+DT"
|
std = "+DT+DML"
|
||||||
|
|
||||||
|
stds["DML"] = {
|
||||||
|
read_globals = {
|
||||||
|
"MODS_HOOKS", "MODS_HOOKS_BY_FILE", "Log",
|
||||||
|
Mods = { fields = {
|
||||||
|
lua = { fields = { "debug", "io", "ffi", "os" }},
|
||||||
|
hook = { fields = {
|
||||||
|
"set",
|
||||||
|
"set_on_file",
|
||||||
|
"enable",
|
||||||
|
"enable_by_file",
|
||||||
|
"remove",
|
||||||
|
"front",
|
||||||
|
"_get_item",
|
||||||
|
"_get_item_hook",
|
||||||
|
"_patch",
|
||||||
|
}},
|
||||||
|
"original_require",
|
||||||
|
"require_store",
|
||||||
|
"original_class",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
stds["DT"] = {
|
stds["DT"] = {
|
||||||
read_globals = {
|
read_globals = {
|
||||||
|
@ -32,13 +55,9 @@ stds["DT"] = {
|
||||||
Managers = { fields = {
|
Managers = { fields = {
|
||||||
"mod", "event", "chat"
|
"mod", "event", "chat"
|
||||||
}},
|
}},
|
||||||
Mods = { fields = {
|
|
||||||
lua = { fields = { "debug", "io", "ffi", "os" }},
|
|
||||||
"original_require",
|
|
||||||
"require_store",
|
|
||||||
}},
|
|
||||||
"Crashify","Keyboard","Mouse","Application","Color","Quarternion","Vector3","Vector2","RESOLUTION_LOOKUP",
|
"Crashify","Keyboard","Mouse","Application","Color","Quarternion","Vector3","Vector2","RESOLUTION_LOOKUP",
|
||||||
"ModManager", "Utf8", "StateGame", "ResourcePackage", "class", "Gui", "fassert", "printf", "__print", "ffi",
|
"ModManager", "Utf8", "StateGame", "ResourcePackage", "class", "Gui", "fassert", "printf", "__print", "ffi",
|
||||||
|
"class",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
Mods.original_class = Mods.original_class or class
|
local original_class = Mods.original_class or class
|
||||||
|
Mods.original_class = original_class
|
||||||
|
|
||||||
local _G = _G
|
local _G = _G
|
||||||
local rawget = rawget
|
local rawget = rawget
|
||||||
local rawset = rawset
|
local rawset = rawset
|
||||||
|
|
||||||
|
-- The `__index` metamethod maps a proper identifier `CLASS.MyClassName` to the
|
||||||
|
-- stringified version of the key: `"MyClassName"`.
|
||||||
|
-- This allows using LuaCheck for the stringified class names in hook parameters.
|
||||||
_G.CLASS = _G.CLASS or setmetatable({}, {
|
_G.CLASS = _G.CLASS or setmetatable({}, {
|
||||||
__index = function(_, key)
|
__index = function(_, key)
|
||||||
return key
|
return key
|
||||||
|
@ -11,7 +15,7 @@ _G.CLASS = _G.CLASS or setmetatable({}, {
|
||||||
})
|
})
|
||||||
|
|
||||||
class = function(class_name, super_name, ...)
|
class = function(class_name, super_name, ...)
|
||||||
local result = Mods.original_class(class_name, super_name, ...)
|
local result = original_class(class_name, super_name, ...)
|
||||||
if not rawget(_G, class_name) then
|
if not rawget(_G, class_name) then
|
||||||
rawset(_G, class_name, result)
|
rawset(_G, class_name, result)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,27 +1,24 @@
|
||||||
--[[
|
|
||||||
Mods Hook v2:
|
|
||||||
New version with better control
|
|
||||||
--]]
|
|
||||||
|
|
||||||
-- Hook structure
|
-- Hook structure
|
||||||
MODS_HOOKS = MODS_HOOKS or {}
|
MODS_HOOKS = MODS_HOOKS or {}
|
||||||
MODS_HOOKS_BY_FILE = MODS_HOOKS_BY_FILE or {}
|
MODS_HOOKS_BY_FILE = MODS_HOOKS_BY_FILE or {}
|
||||||
|
|
||||||
|
local function NOOP() end
|
||||||
|
|
||||||
local item_template = {
|
local item_template = {
|
||||||
name = "",
|
name = "",
|
||||||
func = EMPTY_FUNC,
|
func = NOOP,
|
||||||
hooks = {},
|
hooks = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
local item_hook_template = {
|
local item_hook_template = {
|
||||||
name = "",
|
name = "",
|
||||||
func = EMPTY_FUNC,
|
func = NOOP,
|
||||||
enable = false,
|
enable = false,
|
||||||
exec = EMPTY_FUNC,
|
exec = NOOP,
|
||||||
}
|
}
|
||||||
local Log = Log
|
local Log = Log
|
||||||
|
|
||||||
local print_log_info = function(mod_name, message)
|
local function print_log_info(mod_name, message)
|
||||||
Log = Log or rawget(_G, "Log")
|
Log = Log or rawget(_G, "Log")
|
||||||
if Log then
|
if Log then
|
||||||
Log._info(mod_name, message)
|
Log._info(mod_name, message)
|
||||||
|
@ -30,151 +27,17 @@ local print_log_info = function(mod_name, message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local print_log_warning = function(mod_name, message)
|
|
||||||
Log = Log or rawget(_G, "Log")
|
|
||||||
if Log then
|
|
||||||
Log._warning(mod_name, message)
|
|
||||||
else
|
|
||||||
print("[" .. mod_name .. "]: " .. message)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Mods.hook = {
|
|
||||||
--
|
|
||||||
-- Set hook
|
|
||||||
--
|
|
||||||
set = function(mod_name, func_name, hook_func)
|
|
||||||
local item = Mods.hook._get_item(func_name)
|
|
||||||
local item_hook = Mods.hook._get_item_hook(item, mod_name)
|
|
||||||
|
|
||||||
print_log_info(mod_name, "Hooking " .. func_name)
|
|
||||||
|
|
||||||
item_hook.enable = true
|
|
||||||
item_hook.func = hook_func
|
|
||||||
|
|
||||||
Mods.hook._patch()
|
|
||||||
end,
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Set hook on every instance of the given file
|
|
||||||
--
|
|
||||||
set_on_file = function(mod_name, filepath, func_name, hook_func)
|
|
||||||
-- Add hook create function to list for the file
|
|
||||||
MODS_HOOKS_BY_FILE[filepath] = MODS_HOOKS_BY_FILE[filepath] or {}
|
|
||||||
local hook_create_func = function(this_filepath, this_index)
|
|
||||||
local dynamic_func_name = "Mods.require_store[\"" .. this_filepath .. "\"][" .. tostring(this_index) .. "]." .. func_name
|
|
||||||
Mods.hook.set(mod_name, dynamic_func_name, hook_func, false)
|
|
||||||
end
|
|
||||||
table.insert(MODS_HOOKS_BY_FILE[filepath], hook_create_func)
|
|
||||||
|
|
||||||
-- Add the new hook to every instance of the file
|
|
||||||
local all_file_instances = Mods.require_store[filepath]
|
|
||||||
if all_file_instances then
|
|
||||||
for i, item in ipairs(all_file_instances) do
|
|
||||||
if item then
|
|
||||||
hook_create_func(filepath, i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Enable/Disable hook
|
|
||||||
--
|
|
||||||
enable = function(value, mod_name, func_name)
|
|
||||||
for _, item in ipairs(MODS_HOOKS) do
|
|
||||||
if item.name == func_name or func_name == nil then
|
|
||||||
for _, hook in ipairs(item.hooks) do
|
|
||||||
if hook.name == mod_name then
|
|
||||||
hook.enable = value
|
|
||||||
Mods.hook._patch()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return
|
|
||||||
end,
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Enable all hooks on a stored file
|
|
||||||
--
|
|
||||||
enable_by_file = function(filepath, store_index)
|
|
||||||
local all_file_instances = Mods.require_store[filepath]
|
|
||||||
local file_instance = all_file_instances and all_file_instances[store_index]
|
|
||||||
|
|
||||||
local all_file_hooks = MODS_HOOKS_BY_FILE[filepath]
|
|
||||||
|
|
||||||
if all_file_hooks and file_instance then
|
|
||||||
for i, hook_create_func in ipairs(all_file_hooks) do
|
|
||||||
hook_create_func(filepath, store_index)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Remove hook from chain
|
|
||||||
--
|
|
||||||
["remove"] = function(func_name, mod_name)
|
|
||||||
for i, item in ipairs(MODS_HOOKS) do
|
|
||||||
if item.name == func_name then
|
|
||||||
if mod_name ~= nil then
|
|
||||||
for j, hook in ipairs(item.hooks) do
|
|
||||||
if hook.name == mod_name then
|
|
||||||
table.remove(item.hooks, j)
|
|
||||||
|
|
||||||
Mods.hook._patch()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local item_name = "MODS_HOOKS[" .. tostring(i) .. "]"
|
|
||||||
|
|
||||||
-- Restore orginal function
|
|
||||||
assert(loadstring(item.name .. " = " .. item_name .. ".func"))()
|
|
||||||
|
|
||||||
-- Remove hook function
|
|
||||||
table.remove(MODS_HOOKS, i)
|
|
||||||
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return
|
|
||||||
end,
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Move hook to front of the hook chain
|
|
||||||
--
|
|
||||||
front = function(mod_name, func_name)
|
|
||||||
for _, item in ipairs(MODS_HOOKS) do
|
|
||||||
if item.name == func_name or func_name == nil then
|
|
||||||
for i, hook in ipairs(item.hooks) do
|
|
||||||
if hook.name == mod_name then
|
|
||||||
local saved_hook = table.clone(hook)
|
|
||||||
table.remove(item.hooks, i)
|
|
||||||
table.insert(item.hooks, saved_hook)
|
|
||||||
|
|
||||||
Mods.hook._patch()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return
|
|
||||||
end,
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Get function by function name
|
-- Get function by function name
|
||||||
--
|
--
|
||||||
_get_func = function(func_name)
|
local function get_func(func_name)
|
||||||
return assert(loadstring("return " .. func_name))()
|
return assert(loadstring("return " .. func_name))()
|
||||||
end,
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Get item by function name
|
-- Get item by function name
|
||||||
--
|
--
|
||||||
_get_item = function(func_name)
|
local function get_item(func_name)
|
||||||
-- Find existing item
|
-- Find existing item
|
||||||
for _, item in ipairs(MODS_HOOKS) do
|
for _, item in ipairs(MODS_HOOKS) do
|
||||||
if item.name == func_name then
|
if item.name == func_name then
|
||||||
|
@ -185,18 +48,18 @@ Mods.hook = {
|
||||||
-- Create new item
|
-- Create new item
|
||||||
local item = table.clone(item_template)
|
local item = table.clone(item_template)
|
||||||
item.name = func_name
|
item.name = func_name
|
||||||
item.func = Mods.hook._get_func(func_name)
|
item.func = get_func(func_name)
|
||||||
|
|
||||||
-- Save
|
-- Save
|
||||||
table.insert(MODS_HOOKS, item)
|
table.insert(MODS_HOOKS, item)
|
||||||
|
|
||||||
return item
|
return item
|
||||||
end,
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Get item hook by mod name
|
-- Get item hook by mod name
|
||||||
--
|
--
|
||||||
_get_item_hook = function(item, mod_name)
|
local function get_item_hook(item, mod_name)
|
||||||
-- Find existing item
|
-- Find existing item
|
||||||
for _, hook in ipairs(item.hooks) do
|
for _, hook in ipairs(item.hooks) do
|
||||||
if hook.name == mod_name then
|
if hook.name == mod_name then
|
||||||
|
@ -212,12 +75,12 @@ Mods.hook = {
|
||||||
table.insert(item.hooks, 1, item_hook)
|
table.insert(item.hooks, 1, item_hook)
|
||||||
|
|
||||||
return item_hook
|
return item_hook
|
||||||
end,
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- If settings are changed the hook itself needs to be updated
|
-- If settings are changed the hook itself needs to be updated
|
||||||
--
|
--
|
||||||
_patch = function(mods_hook_item)
|
local function patch()
|
||||||
for i, item in ipairs(MODS_HOOKS) do
|
for i, item in ipairs(MODS_HOOKS) do
|
||||||
local item_name = "MODS_HOOKS[" .. i .. "]"
|
local item_name = "MODS_HOOKS[" .. i .. "]"
|
||||||
|
|
||||||
|
@ -270,5 +133,143 @@ Mods.hook = {
|
||||||
-- Patch orginal function call
|
-- Patch orginal function call
|
||||||
assert(loadstring(item.name .. " = " .. item_name .. ".hooks[" .. last_j .. "].exec"))()
|
assert(loadstring(item.name .. " = " .. item_name .. ".hooks[" .. last_j .. "].exec"))()
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Set hook
|
||||||
|
--
|
||||||
|
local function set(mod_name, func_name, hook_func)
|
||||||
|
local item = get_item(func_name)
|
||||||
|
local item_hook = get_item_hook(item, mod_name)
|
||||||
|
|
||||||
|
print_log_info(mod_name, "Hooking " .. func_name)
|
||||||
|
|
||||||
|
item_hook.enable = true
|
||||||
|
item_hook.func = hook_func
|
||||||
|
|
||||||
|
patch()
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Set hook on every instance of the given file
|
||||||
|
--
|
||||||
|
local function set_on_file(mod_name, filepath, func_name, hook_func)
|
||||||
|
-- Add hook create function to list for the file
|
||||||
|
MODS_HOOKS_BY_FILE[filepath] = MODS_HOOKS_BY_FILE[filepath] or {}
|
||||||
|
local hook_create_func = function(this_filepath, this_index)
|
||||||
|
local dynamic_func_name = string.format(
|
||||||
|
"Mods.require_store[\"%s\"][%i].%s",
|
||||||
|
this_filepath, this_index, func_name
|
||||||
|
)
|
||||||
|
set(mod_name, dynamic_func_name, hook_func, false)
|
||||||
|
end
|
||||||
|
table.insert(MODS_HOOKS_BY_FILE[filepath], hook_create_func)
|
||||||
|
|
||||||
|
-- Add the new hook to every instance of the file
|
||||||
|
local all_file_instances = Mods.require_store[filepath]
|
||||||
|
if all_file_instances then
|
||||||
|
for i, item in ipairs(all_file_instances) do
|
||||||
|
if item then
|
||||||
|
hook_create_func(filepath, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Enable/Disable hook
|
||||||
|
--
|
||||||
|
local function enable(value, mod_name, func_name)
|
||||||
|
for _, item in ipairs(MODS_HOOKS) do
|
||||||
|
if item.name == func_name or func_name == nil then
|
||||||
|
for _, hook in ipairs(item.hooks) do
|
||||||
|
if hook.name == mod_name then
|
||||||
|
hook.enable = value
|
||||||
|
patch()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Enable all hooks on a stored file
|
||||||
|
--
|
||||||
|
local function enable_by_file(filepath, store_index)
|
||||||
|
local all_file_instances = Mods.require_store[filepath]
|
||||||
|
local file_instance = all_file_instances and all_file_instances[store_index]
|
||||||
|
|
||||||
|
local all_file_hooks = MODS_HOOKS_BY_FILE[filepath]
|
||||||
|
|
||||||
|
if all_file_hooks and file_instance then
|
||||||
|
for _, hook_create_func in ipairs(all_file_hooks) do
|
||||||
|
hook_create_func(filepath, store_index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Remove hook from chain
|
||||||
|
--
|
||||||
|
local function remove(func_name, mod_name)
|
||||||
|
for i, item in ipairs(MODS_HOOKS) do
|
||||||
|
if item.name == func_name then
|
||||||
|
if mod_name ~= nil then
|
||||||
|
for j, hook in ipairs(item.hooks) do
|
||||||
|
if hook.name == mod_name then
|
||||||
|
table.remove(item.hooks, j)
|
||||||
|
|
||||||
|
patch()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local item_name = "MODS_HOOKS[" .. tostring(i) .. "]"
|
||||||
|
|
||||||
|
-- Restore orginal function
|
||||||
|
assert(loadstring(item.name .. " = " .. item_name .. ".func"))()
|
||||||
|
|
||||||
|
-- Remove hook function
|
||||||
|
table.remove(MODS_HOOKS, i)
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Move hook to front of the hook chain
|
||||||
|
--
|
||||||
|
local function front(mod_name, func_name)
|
||||||
|
for _, item in ipairs(MODS_HOOKS) do
|
||||||
|
if item.name == func_name or func_name == nil then
|
||||||
|
for i, hook in ipairs(item.hooks) do
|
||||||
|
if hook.name == mod_name then
|
||||||
|
local saved_hook = table.clone(hook)
|
||||||
|
table.remove(item.hooks, i)
|
||||||
|
table.insert(item.hooks, saved_hook)
|
||||||
|
|
||||||
|
patch()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
Mods.hook = {
|
||||||
|
set = set,
|
||||||
|
set_on_file = set_on_file,
|
||||||
|
enable = enable,
|
||||||
|
enable_by_file = enable_by_file,
|
||||||
|
remove = remove,
|
||||||
|
front = front,
|
||||||
|
_get_item = get_item,
|
||||||
|
_get_item_hook = get_item_hook,
|
||||||
|
_patch = patch,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
local loader = {}
|
local loader = {}
|
||||||
|
|
||||||
Mods = {
|
Mods = {
|
||||||
hook = {},
|
|
||||||
lua = setmetatable({}, {
|
lua = setmetatable({}, {
|
||||||
__index = { debug = debug, io = io, ffi = ffi, os = os },
|
__index = { debug = debug, io = io, ffi = ffi, os = os },
|
||||||
}),
|
}),
|
||||||
|
@ -11,7 +10,7 @@ Mods = {
|
||||||
|
|
||||||
dofile("scripts/mods/dml/require")
|
dofile("scripts/mods/dml/require")
|
||||||
dofile("scripts/mods/dml/class")
|
dofile("scripts/mods/dml/class")
|
||||||
dofile("scripts/mods/dml/hook")
|
Mods.hook = dofile("scripts/mods/dml/hook")
|
||||||
|
|
||||||
function loader:init(boot_gui, mod_data)
|
function loader:init(boot_gui, mod_data)
|
||||||
local ModLoader = dofile("scripts/mods/dml/mod_loader")
|
local ModLoader = dofile("scripts/mods/dml/mod_loader")
|
||||||
|
|
|
@ -1,30 +1,32 @@
|
||||||
Mods.require_store = Mods.require_store or {}
|
local require_store = Mods.require_store or {}
|
||||||
Mods.original_require = Mods.original_require or require
|
Mods.require_store = require_store
|
||||||
|
|
||||||
|
local original_require = Mods.original_require or require
|
||||||
|
Mods.original_require = original_require
|
||||||
|
|
||||||
local can_insert = function(filepath, new_result)
|
local can_insert = function(filepath, new_result)
|
||||||
local store = Mods.require_store[filepath]
|
local store = require_store[filepath]
|
||||||
if not store or #store == 0 then
|
local num_store = #store
|
||||||
|
if not store or num_store == 0 then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if store[#store] ~= new_result then
|
if store[num_store] ~= new_result then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require = function(filepath, ...)
|
require = function(filepath, ...)
|
||||||
local Mods = Mods
|
local result = original_require(filepath, ...)
|
||||||
|
|
||||||
local result = Mods.original_require(filepath, ...)
|
|
||||||
if result and type(result) == "table" then
|
if result and type(result) == "table" then
|
||||||
|
|
||||||
if can_insert(filepath, result) then
|
if can_insert(filepath, result) then
|
||||||
Mods.require_store[filepath] = Mods.require_store[filepath] or {}
|
require_store[filepath] = require_store[filepath] or {}
|
||||||
local store = Mods.require_store[filepath]
|
local store = require_store[filepath]
|
||||||
|
|
||||||
table.insert(store, result)
|
table.insert(store, result)
|
||||||
|
|
||||||
--print("[Require] #" .. tostring(#store) .. " of " .. filepath)
|
--print("[Require] #" .. tostring(#store) .. " of " .. filepath)
|
||||||
|
local Mods = Mods
|
||||||
if Mods.hook then
|
if Mods.hook then
|
||||||
Mods.hook.enable_by_file(filepath, #store)
|
Mods.hook.enable_by_file(filepath, #store)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue