]> git.lizzy.rs Git - hydra-dragonfire.git/blob - hydra.go
c8f1e6778363355c4600319b9f78407aa52b3e85
[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         lastTime = time.Now()
55         return 1
56 }
57
58 func l_canceled(l *lua.LState) int {
59         l.Push(lua.LBool(canceled))
60         return 1
61 }
62
63 func l_poll(l *lua.LState) int {
64         client, pkt, timeout := doPoll(l, getClients(l))
65         l.Push(convert.PushPkt(l, pkt))
66         if client == nil {
67                 l.Push(lua.LNil)
68         } else {
69                 l.Push(client.userdata)
70         }
71         l.Push(lua.LBool(timeout))
72         return 3
73 }
74
75 func l_close(l *lua.LState) int {
76         for _, client := range getClients(l) {
77                 client.closeConn()
78         }
79
80         return 0
81 }
82
83 func main() {
84         if len(os.Args) < 2 {
85                 panic("missing filename")
86         }
87
88         go func() {
89                 <-signalChannel()
90                 canceled = true
91         }()
92
93         l := lua.NewState(lua.Options{IncludeGoStackTrace: true})
94         defer l.Close()
95
96         arg := l.NewTable()
97         for i, a := range os.Args {
98                 l.RawSetInt(arg, i-1, lua.LString(a))
99         }
100         l.SetGlobal("arg", arg)
101
102         hydra := l.SetFuncs(l.NewTable(), hydraFuncs)
103         l.SetField(hydra, "BS", lua.LNumber(10.0))
104         l.SetField(hydra, "serialize_ver", lua.LNumber(serializeVer))
105         l.SetField(hydra, "proto_ver", lua.LNumber(protoVer))
106         l.SetGlobal("hydra", hydra)
107
108         l.SetField(l.NewTypeMetatable("hydra.auth"), "__index", l.SetFuncs(l.NewTable(), authFuncs))
109         l.SetField(l.NewTypeMetatable("hydra.client"), "__index", l.NewFunction(l_client_index))
110
111         for _, str := range builtinFiles {
112                 if err := l.DoString(str); err != nil {
113                         panic(err)
114                 }
115         }
116
117         if err := l.DoFile(os.Args[1]); err != nil {
118                 panic(err)
119         }
120 }