马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本系列教程目的是让大家掌握Lua基本语法与按键精灵手机版的插件开发制作,丰富按键精灵生态环境,让按键精灵变得更加强大!
本教程中部分知识点参考《Lua程序设计》书籍,有兴趣可以自行购买→传送门←
按键精灵手机版插件的开发标准草案请阅读帖子:https://zimaoxy.com/b/t-3297-1-1.html
紫猫学院也有提供Lua插件开发的VIP教学服务,有兴趣请咨询紫猫老师QQ345911220或微信zimaoxy
前言
在前面课程中,我们已经详细介绍了Lua的一些语法规则、数据类型和函数用法,本节课我们将开发第一个按键精灵手机班插件函数。按键精灵自带的 TracePrint 在输出查看数组的时候会直接显示unknown,在输出查看文本内容的时候,空格等不可见字符无法被立即察觉到,这些都对我们调试脚本造成不便,所以本节课将通过插件函数来解决这个问题,对应紫猫插件中的zm.TracePrint与zm.VarInfo函数。
插件框架
在开发插件之前,建议大家熟读《按键精灵手机版插件的开发标准草案与简易教程》,本节课将在该插件框架上进行进一步的开发,以下是纯框架例子。
[Lua] 纯文本查看 复制代码 local _zimao = {} --这是内部私有table函数
local zimao = {} --这是对外公开table函数
QMPlugin = zimao --通过这行代码, 实现将zimao表中所有函数对外公开
local function try(block) -- 保护执行函数
local tablejoin = function (...)
local result = {}
for _, t in ipairs({...}) do
if type(t) == "table" then
for k, v in pairs(t) do
if type(k) == "number" then table.insert(result, v)
else result[k] = v end
end
else
table.insert(result, t)
end
end
return result
end
-- get the try function
local try = block[1]
assert(try)
-- get catch and finally functions
local funcs = tablejoin(block[2] or {}, block[3] or {})
-- try to call it
local result_error = {}
local results = {pcall(try)}
if not results[1] then
-- run the catch function
if funcs and funcs.catch then
result_error = {funcs.catch(results[2])}
end
end
-- run the finally function
if funcs and funcs.finally then
local result_fin = {funcs.finally(table.unpack(results))}
if #result_fin > 0 then
return table.unpack(result_fin)
end
end
-- ok?
if results[1] and #results > 1 then
return table.unpack(results, 2, #results)
else
if #result_error > 0 then
return table.unpack(result_error)
else
return nil
end
end
end
local function catch(block) --异常捕获函数
return {catch = block[1]}
end
local function finally(block) --最终必定执行函数
return {finally = block[1]}
end
在按键精灵中打印输出插件内部数据
在按键精灵中我们使用TracePrint可以打印输出查看信息,在Lua中我们使用print可以打印输出信息,但是print无法在按键精灵上打印输出,而直接写TracePrint会报错,因为这个TracePrint是按键精灵的命令,并非Lua的命令。所以这里我们要调用按键精灵的LuaAuxLib库里的TracePrint函数实现插件在按键精灵上打印输出数据。但是这个函数有一个局限性,第一个参数是由按键编辑器传入的代码行数,而我们没有办法自动获取代码行号,导致只能输出查看信息,而无法得知这是第几行代码的输出。
为了方便调试脚本,我们先封装一个内部使用的traceprint命令,同时让这个命令在Lua调试环境下使用print函数输出,而在按键精灵调试环境下使用LuaAuxLib.TracePrint打印到按键控制台上。
[Lua] 纯文本查看 复制代码 --由于是常用的内部函数命令, 所以保持独立, 不加入内部table中, 同时也定义local作用域, 避免干扰其他插件
local function traceprint(...) --调用按键精灵的调试输出命令
if QMPlugin then -- 在Lua调试环境下, QMPlugin变量的值是我们插件公开table函数值, 而在按键精灵调试运行环境下, 该变量值被替换为nil
print(...)
else
-- 获取可变长参数的第一个参数值
local line = select(1, ...)
-- 如果第一个参数是字符串, 并且符合格式 _数字 , 则判定为行号意思
if type(line) == "string" and line:match("^%_%d+$") then
-- 第一个参数按照格式 _数字: 传入TracePrint中可实现打印行号功能
LuaAuxLib.TracePrint(line .. ":", table.concat({...}, " ", 2, select("#", ...)))
elseif line == ":" and #{...} > 1 then
-- 第一个参数是冒号 : 时, 表示直接打印输出数据
LuaAuxLib.TracePrint(":", table.concat({...}, " ", 2, select("#", ...)))
else
-- 其他的情况下则加上前缀后, 进行正常输出
LuaAuxLib.TracePrint(":","紫猫学院测试插件:", ...)
end
end
end
获取变量详细信息
我们通过自定义的VarInfo函数返回变量的详细信息内容, 方便打印输出, 函数要求支持可变长参数, 并对每一个参数的数据类型, 长度, 内容都进行输出, 如果遇到table数组数据, 则转换json后打印.
[Lua] 纯文本查看 复制代码
-- zimao是插件框架中的对外公开函数, 这里为了方便阅读, 就不写插件框架的代码了
function zimao.VarInfo(...)
-- 防止无法获取nil参数
local paramCount = select("#", ...)
local varType, printStr, t = "", "", {}
for i = 1, paramCount do
local v = select(i, ...)
try {
function()
varType = type(v)
if varType == "table" then
printStr = "【" .. varType .." " .. tostring(#v) .. "】" .. LuaAuxLib.Encode_GetJsonLib():encode(v)
elseif varType == "number" or varType == "string" then
printStr = "【" .. varType .." " .. tostring(#tostring(v)) .. "】" .. tostring(v)
elseif varType == "boolean" or varType == "null" then
printStr = "【" .. varType .."】" .. tostring(v)
else
printStr = "【" .. varType .."】 未知数据,无法查看!"
end
table.insert( t, #t + 1, printStr )
end,
catch {
function (errors)
-- 下面这个traceprint是我们上面定义过的内部输出命令,注意大小写
traceprint("发生运行时错误!错误代码:VarInfo(),错误信息:", errors)
end
}
}
end
printStr = table.concat( t, ", " )
return printStr
end
在按键精灵中打印输出变量详细信息
上面已经得到了详细的信息数据了,现在我们只要通过LuaAuxLib.TracePrint传入上面函数返回值即可实现打印输出。
[Lua] 纯文本查看 复制代码
-- zimao是插件框架中的对外公开函数, 这里为了方便阅读, 就不写插件框架的代码了
function zimao.TracePrint(...)
-- 通过VarInfo函数获取参数的详细数据信息
local info = zimao.VarInfo(...)
try {
function()
-- 在保护模式下打印输出这个数据内容
traceprint(info)
end,
catch {
function (errors)
traceprint("发生运行时错误!错误代码:TracePrint(),错误信息:", errors)
end
}
}
end
整合代码
通过上面介绍,我们已经将功能全部实现,整合入插件框架中,我们将插件保存为zimaoxy.lua,并放到按键精灵手机助手的Plugin目录下,这里注意不要保存成zimao.lua!
[Lua] 纯文本查看 复制代码
local _zimao = {} --这是内部私有table函数
local zimao = {} --这是对外公开table函数
QMPlugin = zimao --通过这行代码, 实现将zimao表中所有函数对外公开
_zimao.version = "20220306" --插件版本号, 方便自己记忆
local function try(block) -- 保护执行函数
local tablejoin = function (...)
local result = {}
for _, t in ipairs({...}) do
if type(t) == "table" then
for k, v in pairs(t) do
if type(k) == "number" then table.insert(result, v)
else result[k] = v end
end
else
table.insert(result, t)
end
end
return result
end
-- get the try function
local try = block[1]
assert(try)
-- get catch and finally functions
local funcs = tablejoin(block[2] or {}, block[3] or {})
-- try to call it
local result_error = {}
local results = {pcall(try)}
if not results[1] then
-- run the catch function
if funcs and funcs.catch then
result_error = {funcs.catch(results[2])}
end
end
-- run the finally function
if funcs and funcs.finally then
local result_fin = {funcs.finally(table.unpack(results))}
if #result_fin > 0 then
return table.unpack(result_fin)
end
end
-- ok?
if results[1] and #results > 1 then
return table.unpack(results, 2, #results)
else
if #result_error > 0 then
return table.unpack(result_error)
else
return nil
end
end
end
local function catch(block) --异常捕获函数
return {catch = block[1]}
end
local function finally(block) --最终必定执行函数
return {finally = block[1]}
end
-- 常用的内部函数, 不加入私有table中, 直接定义使用
local function traceprint(...) --调用按键精灵的调试输出命令
if QMPlugin then -- 在Lua调试环境下, QMPlugin变量的值是我们插件公开table函数值, 而在按键精灵调试运行环境下, 该变量值被替换为nil
print(...)
else
-- 获取可变长参数的第一个参数值
local line = select(1, ...)
-- 如果第一个参数是字符串, 并且符合格式 _数字 , 则判定为行号意思
if type(line) == "string" and line:match("^%_%d+$") then
-- 第一个参数按照格式 _数字: 传入TracePrint中可实现打印行号功能
LuaAuxLib.TracePrint(line .. ":", table.concat({...}, " ", 2, select("#", ...)))
elseif line == ":" and #{...} > 1 then
-- 第一个参数是冒号 : 时, 表示直接打印输出数据
LuaAuxLib.TracePrint(":", table.concat({...}, " ", 2, select("#", ...)))
else
-- 其他的情况下则加上前缀后, 进行正常输出
LuaAuxLib.TracePrint(":","紫猫学院测试插件:", ...)
end
end
end
-- 实现获取变量信息的插件函数, 需对外公开, 所以使用zimao前缀
function zimao.VarInfo(...)
-- 防止无法获取nil参数
local paramCount = select("#", ...)
local varType, printStr, t = "", "", {}
for i = 1, paramCount do
local v = select(i, ...)
try {
function()
varType = type(v)
if varType == "table" then
printStr = "【" .. varType .." " .. tostring(#v) .. "】" .. LuaAuxLib.Encode_GetJsonLib():encode(v)
elseif varType == "number" or varType == "string" then
printStr = "【" .. varType .." " .. tostring(#tostring(v)) .. "】" .. tostring(v)
elseif varType == "boolean" or varType == "null" then
printStr = "【" .. varType .."】" .. tostring(v)
else
printStr = "【" .. varType .."】 未知数据,无法查看!"
end
table.insert( t, #t + 1, printStr )
end,
catch {
function (errors)
-- 下面这个traceprint是我们上面定义过的内部输出命令,注意大小写
traceprint("发生运行时错误!错误代码:VarInfo(),错误信息:", errors)
end
}
}
end
printStr = table.concat( t, ", " )
return printStr
end
-- 实现打印输出变量详细信息数据, 需对外公开
function zimao.TracePrint(...)
-- 通过VarInfo函数获取参数的详细数据信息
local info = zimao.VarInfo(...)
try {
function()
-- 在保护模式下打印输出这个数据内容
traceprint(info)
end,
catch {
function (errors)
traceprint("发生运行时错误!错误代码:TracePrint(),错误信息:", errors)
end
}
}
end
按键精灵测试
插件完成后,记得要先自己调试运行测试一遍,检查是否有错误,本次代码测试效果如下图:
|