-
Notifications
You must be signed in to change notification settings - Fork 0
/
bot.go
128 lines (110 loc) · 3.02 KB
/
bot.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
package bot
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
"github.com/FrisovanderVeen/mobot/bot/config"
"github.com/FrisovanderVeen/mobot/bot/plugins"
"github.com/bwmarrin/discordgo"
"github.com/fatih/color"
// the airhorn plugin being registered
_ "github.com/FrisovanderVeen/mobot/bot/plugins/airhorn"
// The help plugin being registered
_ "github.com/FrisovanderVeen/mobot/bot/plugins/help"
// The onready plugin being registered
_ "github.com/FrisovanderVeen/mobot/bot/plugins/onready"
// The pingpong plugin being registered
_ "github.com/FrisovanderVeen/mobot/bot/plugins/pingpong"
// The youtube plugin being registered
_ "github.com/FrisovanderVeen/mobot/bot/plugins/youtube"
// The audio plugin being registered
_ "github.com/FrisovanderVeen/mobot/bot/plugins/audio"
)
// Bot is a wrapper for a discordgo session
type Bot struct {
Session *discordgo.Session
Prefix string
Exit chan error
}
// NewBot creates a new bot based on the settings in the configuration file
func NewBot(confloc string) (*Bot, error) {
conf, err := config.GetConfig(confloc)
if err != nil {
return nil, err
}
token := conf.Discord.Token
if token == "" {
return nil, fmt.Errorf("No token specified")
}
dg, err := discordgo.New("Bot " + token)
if err != nil {
return nil, fmt.Errorf("Could not create session: %v", err)
}
bot := &Bot{
Session: dg,
Prefix: conf.Discord.Prefix,
Exit: make(chan error),
}
go func() {
c := color.New(color.FgRed, color.Bold)
for {
select {
case inf := <-plugins.InfChan:
color.Green("[INFO]: %s", inf)
case err := <-plugins.WarnChan:
color.Yellow("[WARNING]: %v", err)
case err := <-plugins.ErrChan:
color.Red("[ERROR]: %v", err)
case err := <-plugins.FatalChan:
c.Printf("[FATAL]: %v\n", err)
bot.Exit <- err
}
}
}()
for name, opts := range conf.Plugins {
addPlugins(name, opts, bot, conf)
}
plugins.Prefix = conf.Discord.Prefix
plugins.Config = conf
return bot, nil
}
func addPlugins(name string, opts config.Plugin, bot *Bot, conf *config.TomlConfig) {
for _, plugin := range plugins.Plugins {
if name == plugin.Name {
if opts.Enabled {
bot.Session.AddHandler(plugin.Action)
plugin.Enabled = true
return
} else if !opts.Enabled {
return
}
}
}
if opts.Necessary {
plugins.FatalChan <- fmt.Errorf("Plugin necessary but not present: %s", name)
} else {
plugins.WarnChan <- fmt.Errorf("Plugin specified in config but not present: %s", name)
}
}
// Run runs the bot and exits if CTRL-C is pressed or if there is a fatal error
func (b *Bot) Run() error {
if err := b.Session.Open(); err != nil {
return fmt.Errorf("Could not open session: %v", err)
}
defer func() {
if err := b.Session.Close(); err != nil {
log.Printf("Could not close session: %v\n", err)
}
}()
plugins.InfChan <- "Bot is now running. Press CTRL-C to exit."
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
select {
case <-sc:
case err := <-b.Exit:
return err
}
return nil
}