EigeenLoader/EigeenLoader.lua

247 lines
6.1 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 猫猫虫的 LuaEngine 插件管理框架
-- @version: 1.0.4
--
-- 自动加载以下目录的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")
-- consts
local MODULE_ROOT = "./Lua/eigeen_modules"
-- local NON_ACTIVE_MAPS = {301, 302, 303, 305, 306}
-- globals
-- 所有模块列表仅在初始化时加载。后续处理都基于此列表因此增删改mod需要重载此框架。
local Modules = {}
local Ctx = {}
-- 需要执行的模块函数,每次执行前进行处理。
local ExecuteModules = {}
-- 上一次使用的武器ID用于判断武器是否变更。
local LastWeaponType = 0
-- 上一次的地图ID
local LastMapID = 0
local function isIn(tbl, target)
for key, value in pairs(tbl) do
if target == value then
return true
end
end
return false
end
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 == "in" then
setCondResult(isIn(condVal, value))
elseif key == "nin" then
setCondResult(not 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
}
-- local MetaCtx = {
-- Speed = Speed:new(Ctx.playerData),
-- Keypad = Keypad
-- }
-- MetaCtx.__index = MetaCtx
-- setmetatable(Ctx, MetaCtx)
-- 建立遍历专用表而不是遍历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()
executeOnInit(Modules)
end
function on_switch_scenes()
executeOnSwitchScenes(Ctx, ExecuteModules)
end
function on_monster_create()
end
function on_monster_destroy()
end