From 7ab6930f270a4d77a6629ed0a25017ad90a0ebac Mon Sep 17 00:00:00 2001 From: Meo597 <197331664+Meo597@users.noreply.github.com> Date: Sun, 4 Oct 2026 07:12:54 +0800 Subject: [PATCH] refactor: move push helpers to common and use xlua as the import alias --- app/dns/lua.go | 20 ++++++++++---------- app/dns/script.go | 8 ++++---- app/router/lua.go | 34 +++++++++++++++++----------------- app/router/script.go | 8 ++++---- common/lua/lua.go | 3 ++- common/lua/utils.go | 21 +++++++++++++++++++++ 6 files changed, 58 insertions(+), 36 deletions(-) diff --git a/app/dns/lua.go b/app/dns/lua.go index 6eb7c1c3a..8185e7201 100644 --- a/app/dns/lua.go +++ b/app/dns/lua.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/xtls/xray-core/common/errors" - luamgr "github.com/xtls/xray-core/common/lua" + xlua "github.com/xtls/xray-core/common/lua" "github.com/xtls/xray-core/common/net" featureDNS "github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/dns/localdns" @@ -82,9 +82,9 @@ func registerLua(L *lua.LState, servers []luaDNSServer, client featureDNS.Client } else { ips, ttl, err = client.query(ctx, string(domain), option) } - luamgr.PushUserData(L, ips) - L.Push(lua.LNumber(ttl)) - luamgr.PushError(L, err) + xlua.PushUserData(L, ips) + xlua.PushNumber(L, ttl) + xlua.PushError(L, err) return 3 })) serverList.RawSetInt(i+1, server) @@ -119,9 +119,9 @@ func newLuaClientQuery(L *lua.LState, client featureDNS.Client) *lua.LFunction { return 0 } ips, ttl, err := client.LookupIP(string(domain), option) - luamgr.PushUserData(L, ips) - L.Push(lua.LNumber(ttl)) - luamgr.PushError(L, err) + xlua.PushUserData(L, ips) + xlua.PushNumber(L, ttl) + xlua.PushError(L, err) return 3 }) } @@ -144,17 +144,17 @@ func (s *DNS) callLuaHook(L *lua.LState, domain string, option featureDNS.IPOpti } func readLuaDNSResult(addresses, ttlValue, errorValue lua.LValue) ([]net.IP, uint32, error) { - if err := luamgr.ReadError(errorValue, "DNS script error must be an error or string"); err != nil { + if err := xlua.ReadError(errorValue, "DNS script error must be an error or string"); err != nil { return nil, 0, err } - ttl, err := luamgr.ReadUint32(ttlValue, "DNS script returned invalid TTL") + ttl, err := xlua.ReadUint32(ttlValue, "DNS script returned invalid TTL") if err != nil { return nil, 0, err } if addresses == lua.LNil { return nil, 0, featureDNS.ErrEmptyResponse } - ips, err := luamgr.ReadUserData[[]net.IP](addresses, "DNS script IPs must be native IP slice userdata") + ips, err := xlua.ReadUserData[[]net.IP](addresses, "DNS script IPs must be native IP slice userdata") if err != nil { return nil, 0, err } diff --git a/app/dns/script.go b/app/dns/script.go index a8e308612..7fc80507f 100644 --- a/app/dns/script.go +++ b/app/dns/script.go @@ -6,7 +6,7 @@ import ( "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/geodata" "github.com/xtls/xray-core/common/log" - luamgr "github.com/xtls/xray-core/common/lua" + xlua "github.com/xtls/xray-core/common/lua" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/features/dns" lua "github.com/yuin/gopher-lua" @@ -16,16 +16,16 @@ const scriptExecutionTimeout = 6 * time.Second type scriptEngine struct { dns *DNS - pool *luamgr.Pool + pool *xlua.Pool } func newScriptEngine(path string, server *DNS) (*scriptEngine, error) { - program, err := luamgr.CompileFile(path) + program, err := xlua.CompileFile(path) if err != nil { return nil, err } e := &scriptEngine{dns: server} - e.pool, err = luamgr.NewPool(server.ctx, scriptExecutionTimeout, program.NewStateFactory( + e.pool, err = xlua.NewPool(server.ctx, scriptExecutionTimeout, program.NewStateFactory( scriptExecutionTimeout*20, func(L *lua.LState) { geodata.RegisterLua(L) diff --git a/app/router/lua.go b/app/router/lua.go index 118b9a55e..5bad76a48 100644 --- a/app/router/lua.go +++ b/app/router/lua.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/xtls/xray-core/common/errors" - luamgr "github.com/xtls/xray-core/common/lua" + xlua "github.com/xtls/xray-core/common/lua" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/features/routing" lua "github.com/yuin/gopher-lua" @@ -37,22 +37,22 @@ func (r *Router) RegisterLua(L *lua.LState) { } balancer, found := (*r.balancers.Load())[string(tag)] if !found { - L.Push(lua.LNil) - luamgr.PushError(L, errors.New("balancer ", tag, " not found")) + xlua.PushNil(L) + xlua.PushError(L, errors.New("balancer ", tag, " not found")) return 2 } outboundTag, err := balancer.PickOutbound() - L.Push(lua.LString(outboundTag)) - luamgr.PushError(L, err) + xlua.PushString(L, outboundTag) + xlua.PushError(L, err) return 2 })) module.RawSetString("FindProcess", L.NewFunction(func(L *lua.LState) int { pid, name, path, err := findProcess(checkLuaContext(L), net.FindProcess) - L.Push(lua.LNumber(pid)) - L.Push(lua.LString(name)) - L.Push(lua.LString(path)) - luamgr.PushError(L, err) + xlua.PushNumber(L, pid) + xlua.PushString(L, name) + xlua.PushString(L, path) + xlua.PushError(L, err) return 4 })) @@ -67,24 +67,24 @@ func registerLuaContext(L *lua.LState) { values := L.CheckUserData(1).Value.(map[string]string) key := L.CheckString(2) if value, found := values[key]; found { - L.Push(lua.LString(value)) + xlua.PushString(L, value) } else { - L.Push(lua.LNil) + xlua.PushNil(L) } return 1 })) methods := L.NewTable() L.SetFuncs(methods, map[string]lua.LGFunction{ "GetSourceIPs": func(L *lua.LState) int { - luamgr.PushUserData(L, checkLuaContext(L).GetSourceIPs()) + xlua.PushUserData(L, checkLuaContext(L).GetSourceIPs()) return 1 }, "GetTargetIPs": func(L *lua.LState) int { - luamgr.PushUserData(L, checkLuaContext(L).GetTargetIPs()) + xlua.PushUserData(L, checkLuaContext(L).GetTargetIPs()) return 1 }, "GetLocalIPs": func(L *lua.LState) int { - luamgr.PushUserData(L, checkLuaContext(L).GetLocalIPs()) + xlua.PushUserData(L, checkLuaContext(L).GetLocalIPs()) return 1 }, "GetAttributes": func(L *lua.LState) int { @@ -129,14 +129,14 @@ func (r *Router) callLuaHook(L *lua.LState, routeCtx routing.Context) (string, s } func readLuaRouteResult(tagValue, ruleValue, errorValue lua.LValue) (string, string, error) { - if err := luamgr.ReadError(errorValue, "routing script error must be an error or string"); err != nil { + if err := xlua.ReadError(errorValue, "routing script error must be an error or string"); err != nil { return "", "", err } - tag, err := luamgr.ReadOptionalString(tagValue, "routing script outboundTag must be a string or nil") + tag, err := xlua.ReadOptionalString(tagValue, "routing script outboundTag must be a string or nil") if err != nil || tag == "" { return "", "", err } - ruleTag, err := luamgr.ReadOptionalString(ruleValue, "routing script ruleTag must be a string") + ruleTag, err := xlua.ReadOptionalString(ruleValue, "routing script ruleTag must be a string") if err != nil { return "", "", err } diff --git a/app/router/script.go b/app/router/script.go index da23d3bd7..164438ca6 100644 --- a/app/router/script.go +++ b/app/router/script.go @@ -8,7 +8,7 @@ import ( "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/geodata" "github.com/xtls/xray-core/common/log" - luamgr "github.com/xtls/xray-core/common/lua" + xlua "github.com/xtls/xray-core/common/lua" "github.com/xtls/xray-core/features/routing" lua "github.com/yuin/gopher-lua" ) @@ -17,16 +17,16 @@ const scriptExecutionTimeout = 6 * time.Second type scriptEngine struct { router *Router - pool *luamgr.Pool + pool *xlua.Pool } func newScriptEngine(path string, router *Router) (*scriptEngine, error) { - program, err := luamgr.CompileFile(path) + program, err := xlua.CompileFile(path) if err != nil { return nil, err } e := &scriptEngine{router: router} - e.pool, err = luamgr.NewPool(router.ctx, scriptExecutionTimeout, program.NewStateFactory( + e.pool, err = xlua.NewPool(router.ctx, scriptExecutionTimeout, program.NewStateFactory( scriptExecutionTimeout*20, func(L *lua.LState) { geodata.RegisterLua(L) diff --git a/common/lua/lua.go b/common/lua/lua.go index 57e562f01..88fd75f14 100644 --- a/common/lua/lua.go +++ b/common/lua/lua.go @@ -1,2 +1,3 @@ -// Package lua provides shared GopherLua programs and state management for Xray scripts. +// Package lua provides shared GopherLua programs, state management, and value +// conversion and validation helpers for Xray scripts. package lua diff --git a/common/lua/utils.go b/common/lua/utils.go index 89ef7553e..f321e6572 100644 --- a/common/lua/utils.go +++ b/common/lua/utils.go @@ -7,6 +7,27 @@ import ( glua "github.com/yuin/gopher-lua" ) +type number interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | + ~float32 | ~float64 +} + +// PushNumber converts a Go number to a Lua number and pushes it. +func PushNumber[T number](L *glua.LState, value T) { + L.Push(glua.LNumber(value)) +} + +// PushString converts a Go string to a Lua string and pushes it. +func PushString(L *glua.LState, value string) { + L.Push(glua.LString(value)) +} + +// PushNil pushes Lua nil. +func PushNil(L *glua.LState) { + L.Push(glua.LNil) +} + // PushUserData pushes a native Go value without copying it. func PushUserData(L *glua.LState, value any) { ud := L.NewUserData()