-- 猫猫虫的 LuaEngine 插件管理框架 -- @version: 1.0.6 -- -- 自动加载以下目录的lua模块: -- ./eigeen_modules -- -- 模块编写: -- 样例: -- return { -- version = 1, -- name = "chong_qiang", -- onTime = onTime, -- conditions = {{ -- type = "weapon", -- value = { -- eq = 7 -- } -- }}, -- priority = 0, -- } -- -- 具体用法请参考具体插件示例 -- local Speed = require("utils.Speed") local Keypad = require("utils.Keypad") local Macro = require("utils.Macro") local Utils = require("utils.Utils") -- consts local MODULE_ROOT = "./Lua/eigeen_modules" -- globals -- 所有模块列表,仅在初始化时加载。后续处理都基于此列表,因此增删改mod需要重载。 local Modules = {} local Ctx = {} -- 需要执行的模块函数,每次执行前进行处理。 local ExecuteModules = {} -- 上一次使用的武器ID,用于判断武器是否变更。 local LastWeaponType = 0 -- 上一次的地图ID local LastMapID = 0 local function loadAllModules() local modules = {} -- 自动导入 local moduleFiles = engine.GetAllFiles(MODULE_ROOT) for _, mFile in pairs(moduleFiles) do -- 模块合法性判断 if mFile.file:sub(-4) ~= ".lua" then goto continueIterModules end local eModule = dofile(MODULE_ROOT .. "/" .. mFile.file) if eModule == nil or eModule.version ~= 1 then goto continueIterModules end table.insert(modules, eModule) ::continueIterModules:: end return modules end local function _checkCondition(value, condValue) local result = true local function setCondResult(_res) if result == false then return end if result == true and _res == false then result = false return end end for key, condVal in pairs(condValue) do if key == "eq" then setCondResult(value == condVal) elseif key == "gt" then setCondResult(value > condVal) elseif key == "lt" then setCondResult(value < condVal) elseif key == "ne" then setCondResult(value ~= condVal) elseif key == "ge" then setCondResult(value >= condVal) elseif key == "le" then setCondResult(value <= condVal) elseif key == "tin" then setCondResult(Utils:IsIn(condVal, value)) elseif key == "nin" then setCondResult(not Utils:IsIn(condVal, value)) else setCondResult(false) end end return result end local function checkCondition(ctx, module) local conds = module.conditions if conds == nil or #conds == 0 then return true end local result = true local function setCondResult(_res) if result == false then return end if result == true and _res == false then result = false return end end for _, cond in ipairs(conds) do if type(cond) == "function" then setCondResult(cond(ctx)) elseif cond.type == "weapon" then setCondResult(_checkCondition(ctx.playerData.Weapon.type, cond.value)) elseif cond.type == "map" then setCondResult(_checkCondition(ctx.worldData.MapId, cond.value)) end end return result end local function executeOnInit(modules) for _, module in ipairs(modules) do if module.onInit ~= nil then module.onInit() end end end local function executeOnSwitchScenes(ctx, modules) for _, module in ipairs(modules) do if module.onSwitchScenes ~= nil then module.onSwitchScenes(ctx) end end end local function executeOnImgui(ctx, modules) for _, module in ipairs(modules) do if module.onImgui ~= nil then module.onImgui(ctx) end end end local function executeOnTime(ctx, modules) for _, module in ipairs(modules) do if module.onTime ~= nil then module.onTime(ctx) end end end local function buildExecuteModules(ctx) local exeModules = {} -- 条件检查 for _, module in ipairs(Modules) do if checkCondition(ctx, module) then table.insert(exeModules, module) end end -- 优先级调整 for i = 1, #exeModules do if exeModules[i].priority == nil or exeModules[i].priority < 0 then exeModules[i].priority = 0 end end table.sort(exeModules, function(m1, m2) return m1.priority > m2.priority end) return exeModules end -- Hooks function on_time() local playerData = engine.Player:new() Ctx = { playerData = playerData, worldData = engine.World:new(), questData = engine.Quest:new(), Speed = Speed:new(playerData), Keypad = Keypad, Macro = Macro } -- 一键重载功能 -- 同时按下左右花括号键 Keypad.UseChronoscope({219, 221}, 1, function () on_init() ExecuteModules = buildExecuteModules(Ctx) Message("已重载所有模块") return end) -- 建立遍历专用表,而不是遍历modules主表。条件判断操作更改后刷新遍历专用表。 local wpType = Ctx.playerData.Weapon.type if Ctx.playerData.Weapon.type ~= LastWeaponType then ExecuteModules = buildExecuteModules(Ctx) LastWeaponType = Ctx.playerData.Weapon.type end if Ctx.worldData.MapId ~= LastMapID then ExecuteModules = buildExecuteModules(Ctx) LastMapID = Ctx.worldData.MapId end -- 执行onTime方法 executeOnTime(Ctx, ExecuteModules) end function on_imgui() executeOnImgui(Ctx, ExecuteModules) end function on_init() Modules = loadAllModules() ExecuteModules = {} executeOnInit(Modules) end function on_switch_scenes() executeOnSwitchScenes(Ctx, ExecuteModules) end function on_monster_create() end function on_monster_destroy() end