From 16a577b2b07b89a14900218eea54f342db502468 Mon Sep 17 00:00:00 2001 From: terminaldweller Date: Mon, 3 Jun 2024 18:46:56 -0400 Subject: initial lua script support, fixes #27, fixes #34 --- go.mod | 5 +++++ go.sum | 15 ++++++++++++++ plugins.go | 63 +++++++++++++++++++++++++++++++++++++++++++++----------- plugins/test.lua | 10 ++++++++- 4 files changed, 80 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 49e70f7..e37a96f 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,14 @@ go 1.22.3 require ( github.com/BurntSushi/toml v0.3.1 + github.com/ailncode/gluaxmlpath v0.0.0-20161126153117-6ce478ecb4a6 github.com/alecthomas/chroma/v2 v2.12.0 github.com/google/generative-ai-go v0.11.2 github.com/jackc/pgx/v5 v5.5.5 github.com/lrstanley/girc v0.0.0-20240125042120-9add3166e52e github.com/sashabaranov/go-openai v1.19.3 github.com/yuin/gopher-lua v1.1.1 + gitlab.com/megalithic-llc/gluasocket v0.3.1 golang.org/x/net v0.24.0 google.golang.org/api v0.176.1 ) @@ -34,6 +36,8 @@ require ( github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect @@ -50,4 +54,5 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect google.golang.org/grpc v1.63.2 // indirect google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc // indirect ) diff --git a/go.sum b/go.sum index 7641a04..5b9fb59 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ cloud.google.com/go/longrunning v0.5.6 h1:xAe8+0YaWoCKr9t1+aWe+OeQgN/iJK1fEgZSXm cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/ailncode/gluaxmlpath v0.0.0-20161126153117-6ce478ecb4a6 h1:FM0WudTZ+xeiXPJcs+X1Zg8JXe4vlb9P2GZYqCYjZkk= +github.com/ailncode/gluaxmlpath v0.0.0-20161126153117-6ce478ecb4a6/go.mod h1:Ti1AvV2KUYtHEBX7eYbdAGEfFyKz9+lHrJPcr79Vkng= github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink= github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/chroma/v2 v2.12.0 h1:Wh8qLEgMMsN7mgyG8/qIpegky2Hvzr4By6gEF7cmWgw= @@ -22,6 +24,7 @@ github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW5 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -83,11 +86,17 @@ github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lrstanley/girc v0.0.0-20240125042120-9add3166e52e h1:Y86mAFtJjS4P0atZ6QAKH88TV0ASQYJdIGWiOmJKoNY= github.com/lrstanley/girc v0.0.0-20240125042120-9add3166e52e/go.mod h1:lgrnhcF8bg/Bd5HA5DOb4Z+uGqUqGnp4skr+J2GwVgI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/sashabaranov/go-openai v1.19.3 h1:xJvkU8Tye6MOKLaoqjh7qXYwKiEYGtlmp06cb8179yo= github.com/sashabaranov/go-openai v1.19.3/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -102,6 +111,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= +gitlab.com/megalithic-llc/gluasocket v0.3.1 h1:CtsSTZa3G5WnMbhZ3TgvpLwpVlQv6KjO2mqxNOGrhY4= +gitlab.com/megalithic-llc/gluasocket v0.3.1/go.mod h1:/FBarfbXYDsAPzx16ZUmql2rq7GLU5HeuhaJOC9DeBw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= @@ -186,6 +197,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc h1:LMEBgNcZUqXaP7evD1PZcL6EcDVa2QOFuI+cqM3+AJM= +gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc/go.mod h1:N8UOSI6/c2yOpa/XDz3KVUiegocTziPiqNkeNTMiG1k= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/plugins.go b/plugins.go index fa02615..69b3622 100644 --- a/plugins.go +++ b/plugins.go @@ -4,19 +4,22 @@ import ( "log" "reflect" + "github.com/ailncode/gluaxmlpath" "github.com/lrstanley/girc" lua "github.com/yuin/gopher-lua" + "gitlab.com/megalithic-llc/gluasocket" ) func registerStructAsLuaMetaTable[T any]( luaState *lua.LState, + luaLTable *lua.LTable, checkStruct func(luaState *lua.LState) *T, structType T, metaTableName string, ) { metaTable := luaState.NewTypeMetatable(metaTableName) - luaState.SetGlobal(metaTableName, metaTable) + luaState.SetField(luaLTable, metaTableName, metaTable) luaState.SetField( metaTable, @@ -173,16 +176,10 @@ func luaTableGenFactory[T any]( return tableMethods } -func RegisterCustomLuaTypes(luaState *lua.LState) { - registerStructAsLuaMetaTable[TomlConfig](luaState, checkStruct, TomlConfig{}, "toml_config") - registerStructAsLuaMetaTable[CustomCommand](luaState, checkStruct, CustomCommand{}, "custom_command") - registerStructAsLuaMetaTable[LogModel](luaState, checkStruct, LogModel{}, "log_model") -} - func sendMessageClosure(luaState *lua.LState, client *girc.Client) func(*lua.LState) int { return func(luaState *lua.LState) int { message := luaState.CheckString(1) - target := luaState.CheckString(2) + target := luaState.CheckString(2) //nolint: mnd,gomnd client.Cmd.Message(target, message) @@ -190,17 +187,58 @@ func sendMessageClosure(luaState *lua.LState, client *girc.Client) func(*lua.LSt } } +func ircJoinChannelClosure(luaState *lua.LState, client *girc.Client) func(*lua.LState) int { + return func(luaState *lua.LState) int { + channel := luaState.CheckString(1) + + client.Cmd.Join(channel) + + return 0 + } +} + +func ircPartChannelClosure(luaState *lua.LState, client *girc.Client) func(*lua.LState) int { + return func(luaState *lua.LState) int { + channel := luaState.CheckString(1) + + client.Cmd.Part(channel) + + return 0 + } +} + +func millaModuleLoaderClosure(luaState *lua.LState, client *girc.Client) func(*lua.LState) int { + return func(luaState *lua.LState) int { + exports := map[string]lua.LGFunction{ + "send_message": lua.LGFunction(sendMessageClosure(luaState, client)), + "join_channel": lua.LGFunction(ircJoinChannelClosure(luaState, client)), + "part_channel": lua.LGFunction(ircPartChannelClosure(luaState, client)), + } + millaModule := luaState.SetFuncs(luaState.NewTable(), exports) + + registerStructAsLuaMetaTable[TomlConfig](luaState, millaModule, checkStruct, TomlConfig{}, "toml_config") + registerStructAsLuaMetaTable[CustomCommand](luaState, millaModule, checkStruct, CustomCommand{}, "custom_command") + registerStructAsLuaMetaTable[LogModel](luaState, millaModule, checkStruct, LogModel{}, "log_model") + + luaState.SetGlobal("milla", millaModule) + + luaState.Push(millaModule) + + return 1 + } +} + func RunScript(scriptPath string, client *girc.Client) { luaState := lua.NewState() defer luaState.Close() - RegisterCustomLuaTypes(luaState) - - luaState.SetGlobal("send_message", luaState.NewFunction(sendMessageClosure(luaState, client))) + luaState.PreloadModule("milla", millaModuleLoaderClosure(luaState, client)) + gluasocket.Preload(luaState) + gluaxmlpath.Preload(luaState) log.Print("Running script: ", scriptPath) - err := luaState.DoFile(scriptPath) + err := luaState.DoFile(scriptPath) if err != nil { log.Print(err) } @@ -209,6 +247,7 @@ func RunScript(scriptPath string, client *girc.Client) { func LoadAllPlugins(appConfig *TomlConfig, client *girc.Client) { for _, scriptPath := range appConfig.Plugins { log.Print("Loading plugin: ", scriptPath) + go RunScript(scriptPath, client) } } diff --git a/plugins/test.lua b/plugins/test.lua index 23eab94..afd998c 100644 --- a/plugins/test.lua +++ b/plugins/test.lua @@ -1,11 +1,19 @@ +local milla = require("milla") + local function sleep(n) local t0 = os.clock() while os.clock() - t0 <= n do end end local function printer() + + local config = milla.toml_config.new() + print(config:IrcServer()) + config:IrcServer("irc.libera.chat") + print(config:IrcServer()) + while true do - send_message("Hello, World!", "#warroom") + milla.send_message(config:IrcServer(), "#warroom") sleep(5) end end -- cgit v1.2.3