Lua 引擎是 AutoGo 脚本引擎的一部分,用于执行 Lua 脚本。它提供了丰富的 API 接口,支持与设备交互、文件操作、网络请求等功能。
创建一个 Lua 脚本文件,例如 test.lua,并编写以下代码:
-- 直接使用全局模块,无需 require
-- 输出日志
console.log("Hello, AutoGo!")
-- 获取设备信息
console.log("屏幕宽度: " .. device.width)
console.log("屏幕高度: " .. device.height)重要提示:AutoGo 项目的运行必须要使用 AutoGo 的 VSCode Extension 或者 GoLand 的 Extension 来执行,不能直接使用 go run 或者 go build 命令。
Lua 脚本可以通过以下两种方式执行:
- Embed 方式:将脚本嵌入到 Go 程序中编译执行
- 手动放置方式:将脚本文件手动放到移动设备上,然后根据路径执行
- 创建一个包含所有脚本文件的目录,例如
scripts - 在 Go 代码中使用
embed指令嵌入脚本文件:
package main
import (
"embed"
"log"
"github.com/ZingYao/autogo_scriptengine/lua_engine"
"github.com/ZingYao/autogo_scriptengine/lua_engine/define/android/autogo/all_models"
)
//go:embed scripts/*
var scriptsFS embed.FS
func main() {
// 初始化 Lua 引擎,配置文件系统以支持 require
config := lua_engine.DefaultConfig()
config.FileSystem = scriptsFS
engine := lua_engine.NewLuaEngine(&config)
defer engine.Close()
// 注册所有 autogo 风格模块
engine.RegisterModule(all_models.AllModules...)
// 执行主脚本
err := engine.ExecuteFile("scripts/main.lua")
if err != nil {
log.Fatalf("Failed to execute main.lua: %v", err)
}
}使用 AutoGo 的 VSCode Extension 或 GoLand Extension 来运行项目。
- 将脚本文件手动复制到移动设备的指定目录
- 在 Go 代码中指定脚本路径并执行:
package main
import (
"log"
"github.com/ZingYao/autogo_scriptengine/lua_engine"
"github.com/ZingYao/autogo_scriptengine/lua_engine/define/android/autogo/all_models"
)
func main() {
// 初始化 Lua 引擎
config := lua_engine.DefaultConfig()
engine := lua_engine.NewLuaEngine(&config)
defer engine.Close()
// 注册所有 autogo 风格模块
engine.RegisterModule(all_models.AllModules...)
// 执行设备上的脚本文件
err := engine.ExecuteFile("/sdcard/scripts/main.lua")
if err != nil {
log.Fatalf("Failed to execute main.lua: %v", err)
}
}以下示例演示如何从网络中加载 Lua 代码并执行:
package main
import (
"fmt"
"io"
"net/http"
"log"
"github.com/ZingYao/autogo_scriptengine/lua_engine"
"github.com/ZingYao/autogo_scriptengine/lua_engine/define/android/autogo/all_models"
)
func main() {
// 初始化 Lua 引擎
config := lua_engine.DefaultConfig()
engine := lua_engine.NewLuaEngine(&config)
defer engine.Close()
// 注册所有 autogo 风格模块
engine.RegisterModule(all_models.AllModules...)
// 从网络加载脚本代码
url := "https://example.com/scripts/main.lua"
resp, err := http.Get(url)
if err != nil {
log.Fatalf("Failed to download script: %v", err)
}
defer resp.Body.Close()
// 读取脚本内容
scriptContent, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Failed to read script: %v", err)
}
// 执行脚本
err = engine.ExecuteString(string(scriptContent), "main.lua")
if err != nil {
log.Fatalf("Failed to execute script: %v", err)
}
fmt.Println("Script executed successfully!")
}- 使用
http.Get或其他 HTTP 客户端从网络下载脚本 - 读取下载的内容为字符串
- 使用
ExecuteString方法执行脚本内容 - 可以指定脚本文件名用于错误提示
在 Lua 中,可以使用 require 函数来加载其他 Lua 文件(仅限用户自定义的 Lua 文件)。例如:
-- 加载同目录下的 utils.lua 文件
local utils = require("utils")
-- 调用 utils 中的函数
utils.doSomething()如果文件在子目录中,可以使用点号分隔路径:
-- 加载 lib/utils.lua 文件
local utils = require("lib.utils")AutoGo 脚本引擎提供了两种风格包,所有模块都已通过 Go 代码注入到 Lua 全局环境中,无需使用 require:
- autogo 风格:基于 AutoGo 原生 API
- lrappsoft 风格:基于懒人脚本 API,兼容大部分懒人脚本的 Lua 方法
使用注入模块的示例:
-- autogo 风格:直接使用全局模块
console.log("Hello")
device.width
motion.click(100, 200)
app.openSetting("com.example.app")
-- lrappsoft 风格:直接使用全局模块
log("Hello")
getScreenWidth()
motion.touchDown(1, 100, 200)autogo 风格遵循 Go API 映射规则:Go 导出函数挂到对应模块对象下,方法名按常规小驼峰转换。例如 app.OpenSetting 映射为 app.openSetting,不会额外保留 app.openAppSetting 等历史别名,也不会注册 click(...) 这类全局入口。
Lua autogo define 已按系统拆分。Android 项目使用 lua_engine/define/android/autogo/...,iOS 项目使用 lua_engine/define/ios/autogo/...。
iOS 项目可参考 examples/lua_engine/autogo_ios。iOS 示例只使用 app.openUrl、device.getDisplayInfo、files.*、https.*、opencv/imgui 等 iOS 已实现模块,不使用 Android-only 的 app.startActivity、uiacc、apkctl 或 displayId 参数。
在 Lua 中,使用 return 来导出模块:
-- utils.lua
local utils = {}
function utils.add(a, b)
return a + b
end
function utils.subtract(a, b)
return a - b
end
return utilsLua 引擎支持两种执行模式:
同步执行是默认模式,会阻塞等待脚本执行完成:
// 同步执行文件
err := engine.ExecuteFile("script.lua")
if err != nil {
log.Fatalf("执行失败: %v", err)
}
// 同步执行字符串
err = engine.ExecuteString("print('Hello')", "scripts")
if err != nil {
log.Fatalf("执行失败: %v", err)
}异步执行会在后台运行脚本,不会阻塞当前线程:
// 异步执行文件
err := engine.ExecuteFileWithMode("script.lua", lua_engine.ExecuteModeAsync)
if err != nil {
log.Fatalf("执行失败: %v", err)
}
// 异步执行字符串
err = engine.ExecuteStringWithMode("print('Hello')", lua_engine.ExecuteModeAsync, "scripts")
if err != nil {
log.Fatalf("执行失败: %v", err)
}- 脚本执行时,当前脚本所在目录会自动添加到 Lua 的搜索路径中
- 这意味着你可以直接 require 同目录下的文件,无需指定完整路径
你可以通过 API 添加自定义的 require 搜索路径:
// 添加单个路径
engine.AddRequirePath("/path/to/modules")
// 设置多个路径
engine.SetRequirePaths([]string{
"/path/to/modules",
"/another/path"
})- Lua 脚本文件的扩展名必须是
.lua - require 时不需要添加
.lua扩展名 - 脚本执行时,当前目录会被添加到 Lua 的搜索路径中
- 所有模块都已通过 Go 代码注入到 Lua 全局环境中,无需使用 require
- autogo 风格和 lrappsoft 风格的模块都直接在全局空间可用
- 使用
embed时,需要配置FileSystem为嵌入的文件系统 - 手动放置脚本时,需要确保脚本文件路径正确
- AutoGo 项目的运行必须要使用 AutoGo 的 VSCode Extension 或 GoLand Extension 来执行
-- 直接使用全局模块,无需 require
-- 输出日志
console.log("Hello, AutoGo!")
-- 获取设备信息
console.log("屏幕宽度: " .. device.width)
console.log("屏幕高度: " .. device.height)utils.lua:
-- 工具函数
local utils = {}
function utils.add(a, b)
return a + b
end
function utils.subtract(a, b)
return a - b
end
return utilsmain.lua:
-- 加载工具模块(用户自定义的 Lua 文件)
local utils = require("utils")
-- 直接使用全局模块(无需 require)
console.log("Hello, AutoGo!")
-- 测试工具函数
local sum = utils.add(5, 3)
local difference = utils.subtract(10, 4)
-- 输出结果
console.log("5 + 3 = " .. sum)
console.log("10 - 4 = " .. difference)package main
import (
"embed"
"fmt"
"log"
"github.com/ZingYao/autogo_scriptengine/lua_engine"
"github.com/ZingYao/autogo_scriptengine/lua_engine/define/android/autogo/all_models"
)
//go:embed scripts/*
var scriptsFS embed.FS
func main() {
// 初始化 Lua 引擎,配置文件系统以支持 require
config := lua_engine.DefaultConfig()
config.FileSystem = scriptsFS
engine := lua_engine.NewLuaEngine(&config)
defer engine.Close()
// 注册所有 autogo 风格模块
engine.RegisterModule(all_models.AllModules...)
// 执行主脚本
err := engine.ExecuteFile("scripts/main.lua")
if err != nil {
log.Fatalf("Failed to execute main.lua: %v", err)
}
// 输出执行结果
fmt.Println("Lua autogo style example completed!")
}package main
import (
"fmt"
"log"
"github.com/ZingYao/autogo_scriptengine/lua_engine"
"github.com/ZingYao/autogo_scriptengine/lua_engine/define/android/autogo/all_models"
)
func main() {
// 初始化 Lua 引擎
config := lua_engine.DefaultConfig()
engine := lua_engine.NewLuaEngine(&config)
defer engine.Close()
// 注册所有 autogo 风格模块
engine.RegisterModule(all_models.AllModules...)
// 执行设备上的脚本文件
err := engine.ExecuteFile("/sdcard/scripts/main.lua")
if err != nil {
log.Fatalf("Failed to execute main.lua: %v", err)
}
// 输出执行结果
fmt.Println("Lua autogo style example completed!")
}package main
import (
"embed"
"fmt"
"log"
"github.com/ZingYao/autogo_scriptengine/lua_engine"
"github.com/ZingYao/autogo_scriptengine/lua_engine/define/lrappsoft_models"
)
//go:embed scripts/*
var scriptsFS embed.FS
func main() {
// 初始化 Lua 引擎,配置文件系统以支持 require
config := lua_engine.DefaultConfig()
config.FileSystem = scriptsFS
engine := lua_engine.NewLuaEngine(&config)
defer engine.Close()
// 注册所有 lrappsoft 风格模块
engine.RegisterModule(lrappsoft_models.LrappsoftModules...)
// 执行工具脚本(以便主脚本可以引用)
err := engine.ExecuteFile("scripts/utils.lua")
if err != nil {
log.Fatalf("Failed to execute utils.lua: %v", err)
}
// 执行主脚本
err = engine.ExecuteFile("scripts/main.lua")
if err != nil {
log.Fatalf("Failed to execute main.lua: %v", err)
}
// 输出执行结果
fmt.Println("Lua lrappsoft style example completed!")
}package main
import (
"fmt"
"log"
"github.com/ZingYao/autogo_scriptengine/lua_engine"
"github.com/ZingYao/autogo_scriptengine/lua_engine/define/lrappsoft_models"
)
func main() {
// 初始化 Lua 引擎
config := lua_engine.DefaultConfig()
engine := lua_engine.NewLuaEngine(&config)
defer engine.Close()
// 注册所有 lrappsoft 风格模块
engine.RegisterModule(lrappsoft_models.LrappsoftModules...)
// 执行设备上的脚本文件
err := engine.ExecuteFile("/sdcard/scripts/main.lua")
if err != nil {
log.Fatalf("Failed to execute main.lua: %v", err)
}
// 输出执行结果
fmt.Println("Lua lrappsoft style example completed!")
}当前 Lua 引擎依赖 github.com/ZingYao/go-lua-vm v1.1.0,可以把本仓库生成的 builtin docs JSON 导入 gluals、VS Code 或 JetBrains,以获得 AutoGo/Lua 扩展方法补全、签名提示和中文悬浮文档。
GLua 扩展自身已经内置 Lua 标准库和 GLua 语法糖提示,包括 coroutine.*、debug.*、io.*、math.*、os.*、string.*、table.*、utf8.*、glua.*、glua.json.*、glua.yaml.*、glua.toml.*、glua.codec.*、glua.hash.*、glua.path.*、glua.regex.*、glua.uuid.*、glua.zip.*、glua.event.*、cjson.*、lpeg.*、socket.* 等。本仓库生成的 JSON 只补 AutoGo ScriptEngine 自己暴露的方法。
生成器会读取 go-lua-vm 自带的 builtin-functions.json,如果本项目方法与 GLua 内置名称重叠,会自动跳过本项目条目,避免覆盖 GLua 官方提示。当前 lrappsoft 兼容模块中的 math.tointeger、math.type、math.ult 使用 GLua 内置提示,不在本仓库 JSON 中重复提供。
生成文件位于:
docs/glua_builtin_docs/autogo-scriptengine-common.json:Lua 引擎公共全局函数和核心 table。docs/glua_builtin_docs/autogo-scriptengine-android.json:Android autogo 风格模块。docs/glua_builtin_docs/autogo-scriptengine-ios.json:iOS autogo 风格模块。docs/glua_builtin_docs/autogo-scriptengine-lrappsoft.json:lrappsoft 兼容模块。
Android 项目推荐组合:
{
"glua.builtinDocs": [
"docs/glua_builtin_docs/autogo-scriptengine-common.json",
"docs/glua_builtin_docs/autogo-scriptengine-android.json",
"docs/glua_builtin_docs/autogo-scriptengine-lrappsoft.json"
]
}iOS 项目将 Android 文件替换为 iOS 文件:
{
"glua.builtinDocs": [
"docs/glua_builtin_docs/autogo-scriptengine-common.json",
"docs/glua_builtin_docs/autogo-scriptengine-ios.json"
]
}命令行使用 gluals 时可以重复传入 --gluals-builtin-docs:
gluals \
--gluals-builtin-docs docs/glua_builtin_docs/autogo-scriptengine-common.json \
--gluals-builtin-docs docs/glua_builtin_docs/autogo-scriptengine-android.jsonJetBrains 插件在 Builtin docs JSON files 中逐行添加上述 JSON 路径。修改 JSON 后需要重启语言服务或重新加载 IDE 窗口。
重新生成:
go run ./tools/glua_builtin_docsLua 引擎的示例代码可以在以下 GitHub 地址找到:
- Lua autogo 风格示例:examples/lua_engine/autogo
- Lua lrappsoft 风格示例:examples/lua_engine/lrappsoft
这些示例包含了完整的 Lua 脚本和 Go 代码,展示了如何使用 embed 和 require 功能。