/
cmd-roleme.go
312 lines (283 loc) · 9.21 KB
/
cmd-roleme.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
package main
import (
"fmt"
"strconv"
"strings"
"github.com/bwmarrin/discordgo"
)
//RoleMe stores a roleme event
type RoleMe struct {
Triggers []string //An array of messages to trigger this roleme event
AddRoles []string //An array of roles to add
RemoveRoles []string //An array of roles to remove
CaseSensitive bool //Whether or not the trigger message should be case-sensitive
ChannelIDs []string //An array of channel IDs to apply this roleme event to
}
func commandRoleMe(args []CommandArgument, env *CommandEnvironment) *discordgo.MessageEmbed {
if len(args) == 0 {
roleMeList := guildSettings[env.Guild.ID].RoleMeList
if len(roleMeList) == 0 {
return NewGenericEmbed("RoleMe", "No roleme events found.")
}
listEmbed := NewEmbed().
SetTitle("RoleMe List").
SetDescription("All available roleme entries.").
SetColor(0x1C1C1C)
for i, roleMe := range roleMeList {
listEmbed.AddField("RoleMe Entry #"+strconv.Itoa(i+1), "Triggers: \""+strings.Join(roleMe.Triggers, "\", \"")+"\"")
}
return listEmbed.MessageEmbed
}
rolesToAdd := make([]string, 0)
rolesToRemove := make([]string, 0)
channelIDs := make([]string, 0)
triggers := make([]string, 0)
caseSensitive := false
entriesToDelete := make([]int, 0)
for _, arg := range args {
switch strings.ToLower(arg.Name) {
case "addrole", "roleadd":
if arg.Value == "" {
return NewErrorEmbed("RoleMe Error", "You must supply a value to the addrole argument.")
}
role, err := getRole(env.Guild.ID, arg.Value)
if err != nil {
return NewErrorEmbed("RoleMe Error", "Error finding role %s.", arg.Value)
}
if isStrInSlice(rolesToAdd, role.ID) {
return NewErrorEmbed("RoleMe Error", "You cannot specify the same role to add twice.")
}
if isStrInSlice(rolesToRemove, role.ID) {
return NewErrorEmbed("RoleMe Error", "You cannot specify a role to add if the role is already specified to be removed.")
}
rolesToAdd = append(rolesToAdd, role.ID)
case "removerole", "roleremove", "deleterole", "roledelete":
if arg.Value == "" {
return NewErrorEmbed("RoleMe Error", "You must supply a value to the removerole argument.")
}
role, err := getRole(env.Guild.ID, arg.Value)
if err != nil {
return NewErrorEmbed("RoleMe Error", "Error finding role %s.", arg.Value)
}
if isStrInSlice(rolesToRemove, role.ID) {
return NewErrorEmbed("RoleMe Error", "You cannot specify the same role to remove twice.")
}
if isStrInSlice(rolesToAdd, role.ID) {
return NewErrorEmbed("RoleMe Error", "You cannot specify a role to remove if the role is already specified to be added.")
}
rolesToRemove = append(rolesToRemove, role.ID)
case "casesensitive":
switch arg.Value {
case "true", "t", "1", "yes", "y", "":
caseSensitive = true
case "false", "f", "0", "no", "n":
caseSensitive = false
}
case "channel":
if arg.Value == "" {
return NewErrorEmbed("RoleMe Error", "You must supply a value to the channel argument.")
}
channel, err := getChannel(env.Guild.ID, arg.Value)
if err != nil {
return NewErrorEmbed("RoleMe Error", "Error finding channel %s.", arg.Value)
}
if isStrInSlice(channelIDs, channel.ID) {
return NewErrorEmbed("RoleMe Error", "You cannot specify the same channel twice.")
}
channelIDs = append(channelIDs, channel.ID)
case "trigger", "message", "msg":
if arg.Value == "" {
return NewErrorEmbed("RoleMe Error", "You must supply a value to the trigger argument.")
}
if isStrInSlice(triggers, arg.Value) {
return NewErrorEmbed("RoleMe Error", "You cannot specify the same trigger twice.")
}
triggers = append(triggers, arg.Value)
case "delete", "remove":
if arg.Value == "" {
return NewErrorEmbed("RoleMe Error", "You must supply a value to the delete argument.")
}
entryToDelete, err := strconv.Atoi(arg.Value)
if err != nil {
return NewErrorEmbed("RoleMe Error", "Invalid entry number ``%s``.", arg.Value)
}
if isIntInSlice(entriesToDelete, entryToDelete) {
return NewErrorEmbed("RoleMe Error", "You cannot specify the same event to delete twice.")
}
if entryToDelete <= 0 || entryToDelete > len(guildSettings[env.Guild.ID].RoleMeList) {
return NewErrorEmbed("RoleMe Error", "Unknown entry number ``%s``.", arg.Value)
}
entriesToDelete = append(entriesToDelete, entryToDelete-1)
default:
return NewErrorEmbed("RoleMe Error", "Unknown argument ``%s``.", arg.Name)
}
}
if len(entriesToDelete) > 0 {
newRoleMeList := make([]*RoleMe, 0)
for i, roleMe := range guildSettings[env.Guild.ID].RoleMeList {
keepEntry := true
for _, entryToDelete := range entriesToDelete {
if entryToDelete == i {
keepEntry = false
break
}
}
if keepEntry {
newRoleMeList = append(newRoleMeList, roleMe)
}
}
guildSettings[env.Guild.ID].RoleMeList = newRoleMeList
return NewGenericEmbed("RoleMe", "Deleted the specified roleme entries successfully!")
}
if len(rolesToAdd) == 0 && len(rolesToRemove) == 0 {
return NewErrorEmbed("RoleMe Error", "You must specify either one or more roles to add or one or more roles to remove.")
}
if len(triggers) == 0 {
return NewErrorEmbed("RoleMe Error", "You must specify one or more triggers to trigger this roleme event.")
}
newRoleMe := &RoleMe{
Triggers: triggers,
AddRoles: rolesToAdd,
RemoveRoles: rolesToRemove,
CaseSensitive: caseSensitive,
ChannelIDs: channelIDs,
}
for _, roleMe := range guildSettings[env.Guild.ID].RoleMeList {
for _, trigger := range roleMe.Triggers {
for _, newTrigger := range newRoleMe.Triggers {
if trigger == newTrigger {
return NewErrorEmbed("RoleMe Error", "The trigger ``%s`` already exists!", trigger)
}
}
}
}
guildSettings[env.Guild.ID].RoleMeList = append(guildSettings[env.Guild.ID].RoleMeList, newRoleMe)
return NewGenericEmbed("RoleMe", "Added the roleme event successfully!")
}
func handleRoleMe(roleMe *RoleMe, guildID, channelID, userID string) {
if len(roleMe.ChannelIDs) > 0 {
channelFound := false
for _, roleMeChannelID := range roleMe.ChannelIDs {
if roleMeChannelID == channelID {
channelFound = true
break
}
}
if channelFound == false {
return
}
}
errCount := 0
successCount := 0
for _, roleToAdd := range roleMe.AddRoles {
err := botData.DiscordSession.GuildMemberRoleAdd(guildID, userID, roleToAdd)
if err != nil {
errCount++
} else {
successCount++
}
}
for _, roleToRemove := range roleMe.RemoveRoles {
err := botData.DiscordSession.GuildMemberRoleRemove(guildID, userID, roleToRemove)
if err != nil {
errCount++
} else {
successCount++
}
}
if errCount == 0 {
botData.DiscordSession.ChannelMessageSendEmbed(channelID, NewGenericEmbed("RoleMe", "Edited your roles successfully!"))
} else if errCount < successCount {
botData.DiscordSession.ChannelMessageSendEmbed(channelID, NewGenericEmbed("RoleMe", "There were some errors editing your roles, but there were more successes!"))
} else {
botData.DiscordSession.ChannelMessageSendEmbed(channelID, NewErrorEmbed("RoleMe Error", "There were some errors editing your roles. :c"))
}
}
func getRole(guildID, role string) (*discordgo.Role, error) {
guildRoles, err := botData.DiscordSession.GuildRoles(guildID)
if err != nil {
return nil, err
}
retRole := &discordgo.Role{}
if strings.HasPrefix(role, "<&") && strings.HasSuffix(role, ">") {
roleID := role
roleID = strings.TrimPrefix(roleID, "<&")
roleID = strings.TrimSuffix(roleID, ">")
roleFound := false
for _, guildRole := range guildRoles {
if guildRole.ID == roleID {
retRole = guildRole
roleFound = true
break
}
}
if roleFound == false {
return nil, fmt.Errorf("error finding role by ID %s", roleID)
}
} else {
roleFound := false
for _, guildRole := range guildRoles {
if guildRole.Name == role {
retRole = guildRole
roleFound = true
break
}
}
if roleFound == false {
return nil, fmt.Errorf("error finding role by name %s", role)
}
}
return retRole, nil
}
func getChannel(guildID, channel string) (*discordgo.Channel, error) {
guildChannels, err := botData.DiscordSession.GuildChannels(guildID)
if err != nil {
return nil, err
}
retChannel := &discordgo.Channel{}
if strings.HasPrefix(channel, "<#") && strings.HasSuffix(channel, ">") {
channelID := channel
channelID = strings.TrimPrefix(channelID, "<#")
channelID = strings.TrimSuffix(channelID, ">")
channelFound := false
for _, guildChannel := range guildChannels {
if guildChannel.ID == channelID {
retChannel = guildChannel
channelFound = true
break
}
}
if channelFound == false {
return nil, fmt.Errorf("error finding channel by ID %s", channelID)
}
} else {
channelFound := false
for _, guildChannel := range guildChannels {
if guildChannel.Name == channel {
retChannel = guildChannel
channelFound = true
break
}
}
if channelFound == false {
return nil, fmt.Errorf("error finding channel by name %s", channel)
}
}
return retChannel, nil
}
func isStrInSlice(slice []string, str string) bool {
for _, value := range slice {
if value == str {
return true
}
}
return false
}
func isIntInSlice(slice []int, num int) bool {
for _, value := range slice {
if value == num {
return true
}
}
return false
}