This repository has been archived by the owner on Mar 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cmds.go
140 lines (123 loc) · 4.15 KB
/
cmds.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
package discordgocmds
import (
"fmt"
"strings"
"github.com/bwmarrin/discordgo"
)
// CmdHandler is the main controller of the command
// handler and contains the bot session, the
// registered commands and registers the message
// handler checking messages for commands.
type CmdHandler struct {
discordSession *discordgo.Session
options *CmdHandlerOptions
permHandler PermissionHandler
databaseMiddleware DatabaseMiddleware
registeredCmds map[string]Command
registeredCmdInstances []Command
logger *logger
}
// New creates a new instance of CmdHandler by passing
// the discordgo session, the database middleware instance
// and the command handler options as argument.
func New(session *discordgo.Session, dbMiddleware DatabaseMiddleware, options *CmdHandlerOptions) *CmdHandler {
c := &CmdHandler{
discordSession: session,
options: options,
databaseMiddleware: dbMiddleware,
registeredCmds: make(map[string]Command),
registeredCmdInstances: make([]Command, 0),
logger: newLogger(),
}
c.discordSession.AddHandler(c.messageHandler)
c.discordSession.AddHandler(c.readyHandler)
c.RegisterCommand(new(CmdHelp))
return c
}
// RegisterCommand registers a Command class in the
// command handler and will be available for execution.
func (c *CmdHandler) RegisterCommand(cmd Command) {
c.registeredCmdInstances = append(c.registeredCmdInstances, cmd)
for _, invoke := range cmd.GetInvokes() {
c.registeredCmds[invoke] = cmd
}
}
//////// private functions ////////
func (c *CmdHandler) sendEmbedError(chanID, body, title string) (*discordgo.Message, error) {
emb := &discordgo.MessageEmbed{
Color: cErrorColor,
Description: body,
Title: title,
}
return c.discordSession.ChannelMessageSendEmbed(chanID, emb)
}
//////// discordgo event handlers ////////
func (c *CmdHandler) messageHandler(s *discordgo.Session, e *discordgo.MessageCreate) {
if e.Message.Author.ID == s.State.User.ID {
return
}
if !c.options.ReactToBots && e.Message.Author.Bot {
return
}
channel, err := s.Channel(e.ChannelID)
if err != nil {
c.logger.e.Printf("Failed getting discord channel from ID (%s): %s", e.ChannelID, err.Error())
return
}
if channel.Type != discordgo.ChannelTypeGuildText {
return
}
guildPrefix, err := c.databaseMiddleware.GetGuildPrefix(e.GuildID)
if err != nil {
c.logger.e.Printf("Failed fetching guild prefix from database: %s", err.Error())
}
var pre string
if strings.HasPrefix(e.Message.Content, c.options.Prefix) {
pre = c.options.Prefix
} else if guildPrefix != "" && strings.HasPrefix(e.Message.Content, guildPrefix) {
pre = guildPrefix
} else {
return
}
contSplit := strings.Fields(e.Message.Content)
invoke := contSplit[0][len(pre):]
if c.options.InvokeToLower {
invoke = strings.ToLower(invoke)
}
if cmdInstance, ok := c.registeredCmds[invoke]; ok {
guild, _ := s.Guild(e.GuildID)
cmdArgs := &CommandArgs{
Args: contSplit[1:],
Channel: channel,
CmdHandler: c,
Guild: guild,
Message: e.Message,
Session: s,
User: e.Author,
}
if c.options.DeleteCmdMessages {
s.ChannelMessageDelete(e.ChannelID, e.ID)
}
hasPerm, err := c.permHandler.CheckUserPermission(cmdArgs, s, cmdInstance)
if err != nil {
c.sendEmbedError(channel.ID, fmt.Sprintf("Failed getting permission von database: ```\n%s\n```", err.Error()), "Permission Error")
return
}
if !hasPerm {
c.sendEmbedError(channel.ID, "You are not permitted to use this command!", "Missing permission")
return
}
err = cmdInstance.Exec(cmdArgs)
if err != nil {
c.sendEmbedError(channel.ID, fmt.Sprintf("Failed executing command: ```\n%s\n```", err.Error()), "Command execution failed")
}
}
}
func (c *CmdHandler) readyHandler(s *discordgo.Session, e *discordgo.Ready) {
if c.databaseMiddleware == nil {
panic("Database middleware must be registered")
}
if c.permHandler == nil {
c.permHandler = NewDefaultPermissionHandler(c.databaseMiddleware)
}
}