]> git.lizzy.rs Git - hydra-dragonfire.git/blob - hydra.go
f34ca2bb733f55f03b659a4cc1a4ce6f87e5cab7
[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 //go:embed builtin/base64.lua
32 var builtinBase64 string
33
34 var builtinFiles = []string{
35         builtinLuaX,
36         builtinVector,
37         builtinEscapes,
38         builtinClient,
39         builtinBase64,
40 }
41
42 var hydraFuncs = map[string]lua.LGFunction{
43         "client":   l_client,
44         "dtime":    l_dtime,
45         "canceled": l_canceled,
46         "poll":     l_poll,
47         "close":    l_close,
48 }
49
50 func signalChannel() chan os.Signal {
51         sig := make(chan os.Signal, 1)
52         signal.Notify(sig, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
53         return sig
54 }
55
56 func l_dtime(l *lua.LState) int {
57         l.Push(lua.LNumber(time.Since(lastTime).Seconds()))
58         lastTime = time.Now()
59         return 1
60 }
61
62 func l_canceled(l *lua.LState) int {
63         l.Push(lua.LBool(canceled))
64         return 1
65 }
66
67 func l_poll(l *lua.LState) int {
68         client, pkt, timeout := doPoll(l, getClients(l))
69         l.Push(convert.PushPkt(l, pkt))
70         if client == nil {
71                 l.Push(lua.LNil)
72         } else {
73                 l.Push(client.userdata)
74         }
75         l.Push(lua.LBool(timeout))
76         return 3
77 }
78
79 func l_close(l *lua.LState) int {
80         for _, client := range getClients(l) {
81                 client.closeConn()
82         }
83
84         return 0
85 }
86
87 func main() {
88         if len(os.Args) < 2 {
89                 panic("missing filename")
90         }
91
92         go func() {
93                 <-signalChannel()
94                 canceled = true
95         }()
96
97         l := lua.NewState(lua.Options{IncludeGoStackTrace: true})
98         defer l.Close()
99
100         arg := l.NewTable()
101         for i, a := range os.Args {
102                 l.RawSetInt(arg, i-1, lua.LString(a))
103         }
104         l.SetGlobal("arg", arg)
105
106         hydra := l.SetFuncs(l.NewTable(), hydraFuncs)
107         l.SetField(hydra, "BS", lua.LNumber(10.0))
108         l.SetField(hydra, "serialize_ver", lua.LNumber(serializeVer))
109         l.SetField(hydra, "proto_ver", lua.LNumber(protoVer))
110         l.SetGlobal("hydra", hydra)
111
112         l.SetField(l.NewTypeMetatable("hydra.auth"), "__index", l.SetFuncs(l.NewTable(), authFuncs))
113         l.SetField(l.NewTypeMetatable("hydra.client"), "__index", l.NewFunction(l_client_index))
114         l.SetField(l.NewTypeMetatable("hydra.map"), "__index", l.SetFuncs(l.NewTable(), mapFuncs))
115
116         for _, str := range builtinFiles {
117                 if err := l.DoString(str); err != nil {
118                         panic(err)
119                 }
120         }
121
122         if err := l.DoFile(os.Args[1]); err != nil {
123                 panic(err)
124         }
125 }