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