]> git.lizzy.rs Git - hydra-dragonfire.git/blob - hydra.go
Fix hydra.poll return value order
[hydra-dragonfire.git] / hydra.go
1 package main
2
3 import (
4         _ "embed"
5         "github.com/dragonfireclient/hydra-dragonfire/convert"
6         "github.com/yuin/gopher-lua"
7         "os"
8         "os/signal"
9         "syscall"
10         "time"
11 )
12
13 var lastTime = time.Now()
14 var canceled = false
15
16 var serializeVer uint8 = 28
17 var protoVer uint16 = 39
18
19 //go:embed builtin/luax/init.lua
20 var builtinLuaX string
21
22 //go:embed builtin/vector.lua
23 var builtinVector string
24
25 //go:embed builtin/escapes.lua
26 var builtinEscapes string
27
28 //go:embed builtin/client.lua
29 var builtinClient string
30
31 var builtinFiles = []string{
32         builtinLuaX,
33         builtinVector,
34         builtinEscapes,
35         builtinClient,
36 }
37
38 var hydraFuncs = map[string]lua.LGFunction{
39         "client":   l_client,
40         "dtime":    l_dtime,
41         "canceled": l_canceled,
42         "poll":     l_poll,
43         "close":    l_close,
44 }
45
46 func signalChannel() chan os.Signal {
47         sig := make(chan os.Signal, 1)
48         signal.Notify(sig, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
49         return sig
50 }
51
52 func l_dtime(l *lua.LState) int {
53         l.Push(lua.LNumber(time.Since(lastTime).Seconds()))
54         return 1
55 }
56
57 func l_canceled(l *lua.LState) int {
58         l.Push(lua.LBool(canceled))
59         return 1
60 }
61
62 func l_poll(l *lua.LState) int {
63         client, pkt, timeout := doPoll(l, getClients(l))
64         l.Push(convert.PushPkt(l, pkt))
65         if client == nil {
66                 l.Push(lua.LNil)
67         } else {
68                 l.Push(client.userdata)
69         }
70         l.Push(lua.LBool(timeout))
71         return 3
72 }
73
74 func l_close(l *lua.LState) int {
75         for _, client := range getClients(l) {
76                 client.closeConn()
77         }
78
79         return 0
80 }
81
82 func main() {
83         if len(os.Args) < 2 {
84                 panic("missing filename")
85         }
86
87         go func() {
88                 <-signalChannel()
89                 canceled = true
90         }()
91
92         l := lua.NewState(lua.Options{IncludeGoStackTrace: true})
93         defer l.Close()
94
95         arg := l.NewTable()
96         for i, a := range os.Args {
97                 l.RawSetInt(arg, i-1, lua.LString(a))
98         }
99         l.SetGlobal("arg", arg)
100
101         hydra := l.SetFuncs(l.NewTable(), hydraFuncs)
102         l.SetField(hydra, "BS", lua.LNumber(10.0))
103         l.SetField(hydra, "serialize_ver", lua.LNumber(serializeVer))
104         l.SetField(hydra, "proto_ver", lua.LNumber(protoVer))
105         l.SetGlobal("hydra", hydra)
106
107         l.SetField(l.NewTypeMetatable("hydra.auth"), "__index", l.SetFuncs(l.NewTable(), authFuncs))
108         l.SetField(l.NewTypeMetatable("hydra.client"), "__index", l.NewFunction(l_client_index))
109
110         for _, str := range builtinFiles {
111                 if err := l.DoString(str); err != nil {
112                         panic(err)
113                 }
114         }
115
116         if err := l.DoFile(os.Args[1]); err != nil {
117                 panic(err)
118         }
119 }