Skip to content

Commit

Permalink
fix: 修复 Lua 初始化的过程中遇到的错误
Browse files Browse the repository at this point in the history
1, 去掉 reload 时无意义的报错信息,参见 issue #39
2, 防止初始化过程中由于 OnReceive/OnSend 接口尚未提供导致的报错
  • Loading branch information
dzpao committed Dec 15, 2020
1 parent 8a4d9b9 commit 65f74c4
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 32 deletions.
84 changes: 54 additions & 30 deletions lua-api/lua.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,7 @@ func (api *API) Init() {
return
}

if err := api.Reload(); err != nil {
api.screen.Println("Lua 初始化失败。")
return
}
_ = api.Reload()
}

func (api *API) SetScreen(w printer.Printer) {
Expand All @@ -63,7 +60,7 @@ func (api *API) SetMud(w io.Writer) {
func (api *API) Reload() error {
mainFile := path.Join(api.config.Path, "main.lua")
if _, err := os.Open(mainFile); err != nil {
api.screen.Printf("Load error: %s\n", err)
api.screen.Printf("Load error: %v\n", err)
api.screen.Println("无法打开 lua 主程序,请检查你的配置。")
return err
}
Expand All @@ -80,47 +77,72 @@ func (api *API) Reload() error {

api.lstate = lua.NewState()

l := api.lstate
// 为 Lua 环境提供 API
api.register()

l.SetGlobal("RegEx", l.NewFunction(api.LuaRegEx))
l.SetGlobal("Echo", l.NewFunction(api.LuaEcho))
l.SetGlobal("Print", l.NewFunction(api.LuaPrint))
l.SetGlobal("Run", l.NewFunction(api.LuaRun))
l.SetGlobal("Send", l.NewFunction(api.LuaSend))
l.SetGlobal("AddTimer", l.NewFunction(api.LuaAddTimer))
l.SetGlobal("AddMSTimer", l.NewFunction(api.LuaAddTimer))
l.SetGlobal("DelTimer", l.NewFunction(api.LuaDelTimer))
l.SetGlobal("DelMSTimer", l.NewFunction(api.LuaDelTimer))
l := api.lstate

l.Panic = func(*lua.LState) {
api.Panic(errPanic)
}

if err := l.DoFile(mainFile); err != nil {
l.Close()
api.screen.Printf("Lua 初始化失败:%v\n", err)
api.lstate = nil
return err
}

api.onReceive = lua.P{
Fn: l.GetGlobal("OnReceive"),
NRet: 0,
Protect: true,
}

api.onSend = lua.P{
Fn: l.GetGlobal("OnSend"),
NRet: 1,
Protect: true,
}
// 和 Lua 环境中的钩子相连接
api.hookOn()

api.screen.Println("Lua 环境初始化完成。")

return nil
}

func (api *API) register() {
l := api.lstate

l.SetGlobal("RegEx", l.NewFunction(api.LuaRegEx))
l.SetGlobal("Echo", l.NewFunction(api.LuaEcho))
l.SetGlobal("Print", l.NewFunction(api.LuaPrint))
l.SetGlobal("Run", l.NewFunction(api.LuaRun))
l.SetGlobal("Send", l.NewFunction(api.LuaSend))
l.SetGlobal("AddTimer", l.NewFunction(api.LuaAddTimer))
l.SetGlobal("AddMSTimer", l.NewFunction(api.LuaAddTimer))
l.SetGlobal("DelTimer", l.NewFunction(api.LuaDelTimer))
l.SetGlobal("DelMSTimer", l.NewFunction(api.LuaDelTimer))
}

func (api *API) hookOn() {
l := api.lstate

if v := l.GetGlobal("OnReceive"); v.Type() == lua.LTFunction {
api.onReceive = lua.P{
Fn: v,
NRet: 0,
Protect: true,
}
} else {
api.screen.Println("Lua 环境中未定义 OnReceive 函数,将无法接收游戏数据。")
}

if v := l.GetGlobal("OnSend"); v.Type() == lua.LTFunction {
api.onSend = lua.P{
Fn: v,
NRet: 1,
Protect: true,
}
} else {
api.screen.Println("Lua 环境中未定义 OnSend 函数,将无法获知向游戏发送的数据。")
}
}

func (api *API) OnReceive(raw, input string) {
if api.lstate == nil {
if api.lstate == nil ||
api.onReceive.Fn == nil ||
api.onReceive.Fn.Type() != lua.LTFunction {
return
}

Expand All @@ -132,7 +154,9 @@ func (api *API) OnReceive(raw, input string) {
}

func (api *API) OnSend(cmd string) bool {
if api.lstate == nil {
if api.lstate == nil ||
api.onSend.Fn == nil ||
api.onSend.Fn.Type() != lua.LTFunction {
return true
}

Expand All @@ -149,7 +173,7 @@ func (api *API) OnSend(cmd string) bool {
}

func (api *API) Panic(err error) {
api.screen.Printf("Lua error: [%v]\n", err)
api.screen.Printf("Lua error: %v\n", err)
}

func (api *API) LuaRegEx(l *lua.LState) int {
Expand Down Expand Up @@ -307,6 +331,6 @@ type Timer struct {
func (t *Timer) Emit(l *API) {
err := l.lstate.DoString(`call_timer_actions("` + t.id + `")`)
if err != nil {
l.screen.Printf("Lua Error: %s\n", err)
l.screen.Printf("Lua Error: %v\n", err)
}
}
3 changes: 1 addition & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ func (c *Client) DoCmd(cmd string) {
c.ui.Print(app.VersionDetail())
return
case "/reload-lua":
err := c.lua.Reload()
c.ui.Printf("Error: %s\n", err)
_ = c.lua.Reload()
return
case "/debug":
c.debug = !c.debug
Expand Down

0 comments on commit 65f74c4

Please sign in to comment.