forked from botlabs-gg/yagpdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
events.go
140 lines (115 loc) · 2.92 KB
/
events.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Generates the wrapper event handlers for discordgo events
// The wrappers adds an extra parameter to the handlers which is a redis connection
// And will also recover from panic that occured inside them
package main
import (
"flag"
"fmt"
"go/parser"
"go/token"
"log"
"os"
"path/filepath"
"sort"
"text/template"
)
const templateSource = `// GENERATED using yagpdb/cmd/gen/bot_wrappers.go
// Custom event handlers that adds a redis connection to the handler
// They will also recover from panics
package bot
import (
"context"
"github.com/sirupsen/logrus"
"github.com/jonas747/discordgo"
"runtime/debug"
)
type Event int
const (
{{range $k, $v := .}}
Event{{.Name}} Event = {{$k}}{{end}}
)
var AllDiscordEvents = []Event{ {{range .}}{{if .Discord}}
Event{{.Name}},{{end}}{{end}}
}
type Handler func(ctx context.Context, evt interface{})
var handlers = make([][]*Handler, {{len .}})
func handleEvent(s *discordgo.Session, evt interface{}){
evtId := -10
name := ""
switch evt.(type){ {{range $k, $v := .}}{{if .Discord}}
case *discordgo.{{.Name}}:
evtId = {{$k}}
name = "{{.Name}}"{{end}}{{end}}
default:
return
}
defer func() {
if err := recover(); err != nil {
stack := string(debug.Stack())
logrus.WithField(logrus.ErrorKey, err).WithField("evt", name).Error("Recovered from panic in event handler\n" + stack)
}
}()
ctx := context.WithValue(context.Background(), ContextKeySession, s)
EmitEvent(ctx, EventAllPre, evt)
EmitEvent(ctx, Event(evtId), evt)
EmitEvent(ctx, EventAllPost, evt)
}
`
type Event struct {
Name string
Discord bool
}
var NonStandardEvents = []Event{
Event{"NewGuild", false},
Event{"All", false},
Event{"AllPre", false},
Event{"AllPost", false},
Event{"MemberFetched", false},
}
var (
parsedTemplate = template.Must(template.New("").Parse(templateSource))
flagOut string
)
func init() {
flag.StringVar(&flagOut, "o", "../../bot/wrappers.go", "Output file")
flag.Parse()
}
func CheckErr(errMsg string, err error) {
if err != nil {
fmt.Println(errMsg+":", err)
os.Exit(1)
}
}
func main() {
fs := token.NewFileSet()
parsedFile, err := parser.ParseFile(fs, filepath.Join(os.Getenv("GOPATH"), "src/github.com/jonas747/discordgo/events.go"), nil, 0)
if err != nil {
log.Fatalf("warning: internal error: could not parse events.go: %s", err)
return
}
names := []string{}
for name, _ := range parsedFile.Scope.Objects {
names = append(names, name)
}
sort.Strings(names)
// Create the combined event slice
events := make([]Event, len(names)+len(NonStandardEvents)-1)
copy(events, NonStandardEvents)
i := len(NonStandardEvents)
for _, name := range names {
if name == "Event" {
continue
}
evt := Event{
Name: name,
Discord: true,
}
events[i] = evt
i++
}
file, err := os.Create(flagOut)
CheckErr("Failed creating output file", err)
defer file.Close()
err = parsedTemplate.Execute(file, events)
CheckErr("Failed executing template", err)
}