]> git.lizzy.rs Git - hydra-dragonfire.git/blobdiff - hydra.go
Fix map race condition
[hydra-dragonfire.git] / hydra.go
index 77d7e055e67c02081da943ca034795378c29aa1d..6caff4cb48040c1cf79238ed7f2afabe2dcab3d8 100644 (file)
--- a/hydra.go
+++ b/hydra.go
@@ -2,7 +2,7 @@ package main
 
 import (
        _ "embed"
-       "github.com/Shopify/go-lua"
+       "github.com/yuin/gopher-lua"
        "os"
        "os/signal"
        "syscall"
@@ -10,26 +10,58 @@ import (
 )
 
 var lastTime = time.Now()
-var canceled = false
+var signalChannel chan os.Signal
+
+var serializeVer uint8 = 28
+var protoVer uint16 = 39
+
+//go:embed builtin/luax/init.lua
+var builtinLuaX string
 
 //go:embed builtin/vector.lua
-var vectorLibrary string
+var builtinVector string
+
+//go:embed builtin/escapes.lua
+var builtinEscapes string
+
+//go:embed builtin/client.lua
+var builtinClient string
 
-func l_dtime(l *lua.State) int {
-       l.PushNumber(time.Since(lastTime).Seconds())
+//go:embed builtin/base64.lua
+var builtinBase64 string
+
+var builtinFiles = []string{
+       builtinLuaX,
+       builtinVector,
+       builtinEscapes,
+       builtinClient,
+       builtinBase64,
+}
+
+var hydraFuncs = map[string]lua.LGFunction{
+       "client": l_client,
+       "map":    l_map,
+       "dtime":  l_dtime,
+       "poll":   l_poll,
+       "close":  l_close,
+}
+
+func l_dtime(l *lua.LState) int {
+       l.Push(lua.LNumber(time.Since(lastTime).Seconds()))
        lastTime = time.Now()
        return 1
 }
 
-func l_canceled(l *lua.State) int {
-       l.PushBoolean(canceled)
-       return 1
+func l_poll(l *lua.LState) int {
+       return doPoll(l, getClients(l))
 }
 
-func signalChannel() chan os.Signal {
-       sig := make(chan os.Signal, 1)
-       signal.Notify(sig, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
-       return sig
+func l_close(l *lua.LState) int {
+       for _, client := range getClients(l) {
+               client.closeConn()
+       }
+
+       return 0
 }
 
 func main() {
@@ -37,38 +69,38 @@ func main() {
                panic("missing filename")
        }
 
-       go func() {
-               <-signalChannel()
-               canceled = true
-       }()
+       signalChannel = make(chan os.Signal, 1)
+       signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
 
        l := lua.NewState()
-       lua.OpenLibraries(l)
+       defer l.Close()
 
-       lua.NewLibrary(l, []lua.RegistryFunction{
-               {Name: "client", Function: l_client},
-               {Name: "dtime", Function: l_dtime},
-               {Name: "canceled", Function: l_canceled},
-               {Name: "poll", Function: l_poll},
-       })
+       arg := l.NewTable()
+       for i, a := range os.Args {
+               l.RawSetInt(arg, i-1, lua.LString(a))
+       }
+       l.SetGlobal("arg", arg)
 
-       l.PushNumber(10.0)
-       l.SetField(-2, "BS")
+       hydra := l.SetFuncs(l.NewTable(), hydraFuncs)
+       l.SetField(hydra, "BS", lua.LNumber(10.0))
+       l.SetField(hydra, "serialize_ver", lua.LNumber(serializeVer))
+       l.SetField(hydra, "proto_ver", lua.LNumber(protoVer))
+       l.SetGlobal("hydra", hydra)
 
-       l.SetGlobal("hydra")
+       l.SetField(l.NewTypeMetatable("hydra.client"), "__index", l.NewFunction(l_client_index))
+       l.SetField(l.NewTypeMetatable("hydra.map"), "__index", l.SetFuncs(l.NewTable(), mapFuncs))
 
-       l.NewTable()
-       for i, arg := range os.Args {
-               l.PushString(arg)
-               l.RawSetInt(-2, i - 1)
-       }
-       l.SetGlobal("arg")
+       l.SetField(l.NewTypeMetatable("hydra.comp.auth"), "__index", l.SetFuncs(l.NewTable(), compAuthFuncs))
+       l.SetField(l.NewTypeMetatable("hydra.comp.map"), "__index", l.SetFuncs(l.NewTable(), compMapFuncs))
+       l.SetField(l.NewTypeMetatable("hydra.comp.pkts"), "__index", l.SetFuncs(l.NewTable(), compPktsFuncs))
 
-       if err := lua.DoString(l, vectorLibrary); err != nil {
-               panic(err)
+       for _, str := range builtinFiles {
+               if err := l.DoString(str); err != nil {
+                       panic(err)
+               }
        }
 
-       if err := lua.DoFile(l, os.Args[1]); err != nil {
+       if err := l.DoFile(os.Args[1]); err != nil {
                panic(err)
        }
 }