From c22f81d6cbe1fc335a2591fdb263191954a0e706 Mon Sep 17 00:00:00 2001 From: kageru Date: Tue, 12 Mar 2019 22:37:06 +0100 Subject: [PATCH] added !vc to create temporary voice channels --- CHANGELOG.md | 3 +++ helpers.go | 14 ++++++++++-- main.go | 29 +++++++++++++++++------ voicechannel.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 voicechannel.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ab3eee..55ad094 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Selphybot Changelog Updates are listed in reverse chronological order. +### 1.5 (dev) +- added !vc to create temporary voice channels + ### 1.4 - a copy of each deleted message is now send via DM to the author (suggested by CommanderLook) - seasonal fluff diff --git a/helpers.go b/helpers.go index 7e7cfa1..ee19cfe 100644 --- a/helpers.go +++ b/helpers.go @@ -43,8 +43,8 @@ func isDM(s *discordgo.Session, m *discordgo.MessageCreate) bool { } func getDMChannelFromMessage(s *discordgo.Session, m *discordgo.MessageCreate) *discordgo.Channel { - dm, _ := s.UserChannelCreate(m.Author.ID) - return dm + dm, _ := s.UserChannelCreate(m.Author.ID) + return dm } func isAdmin(u *discordgo.User) bool { @@ -55,3 +55,13 @@ func isAdmin(u *discordgo.User) bool { } return false } + +func getServer() *discordgo.Guild { + server, _ := state.Guild(config.ServerID) + return server +} + +func remove(channels []*discordgo.Channel, position int) []*discordgo.Channel { + channels[len(channels)-1], channels[position] = channels[position], channels[len(channels)-1] + return channels[:len(channels)-1] +} diff --git a/main.go b/main.go index 562e288..91da04b 100644 --- a/main.go +++ b/main.go @@ -11,18 +11,19 @@ import ( var config = readConfig() var commands []*Command +var state *discordgo.State func main() { - dg, err := discordgo.New("Bot " + config.Token) + session, err := discordgo.New("Bot " + config.Token) if err != nil { fmt.Println("error: ", err) return } - defer dg.Close() + defer session.Close() - dg.AddHandler(evaluateMessage) - dg.AddHandler(onJoin) - err = dg.Open() + session.AddHandler(evaluateMessage) + session.AddHandler(onJoin) + err = session.Open() if err != nil { fmt.Println("No connection:\n", err) return @@ -34,7 +35,15 @@ func main() { } defer f.Close() log.SetOutput(f) - dg.UpdateStatus(0, "!help") + session.UpdateStatus(0, "!help") + state = discordgo.NewState() + server, err := session.Guild(config.ServerID) + if err != nil { + fmt.Println("Guild incorrectly configured. Exiting...") + return + } + state.GuildAdd(server) + go checkAndDeleteUnusedChannels(session) addCommands() fmt.Println("Bot running. selphyWoo") @@ -43,6 +52,9 @@ func main() { signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) <-sc + for _, channel := range tempChannels { + session.ChannelDelete(channel.ID) + } fmt.Println("Exiting...") log.Println("Exiting...") } @@ -61,7 +73,7 @@ func addCommands() { registerCommand(Command{Trigger: comm, Type: CommandTypeFullMatch, DMOnly: true, Function: giveAgeRole}) } - // Misc commands + // Fluff registerCommand(Command{Trigger: "o/", Output: "\\o", Type: CommandTypeFullMatch, Cooldown: 10}) registerCommand(Command{Trigger: "\\o", Output: "o/", Type: CommandTypeFullMatch, Cooldown: 10}) registerCommand(Command{Trigger: "\\o/", Output: "/o\\", Type: CommandTypeFullMatch, Cooldown: 10}) @@ -75,6 +87,9 @@ func addCommands() { registerCommand(Command{Trigger: "!welcome", OutputEmbed: getWelcomeEmbed(), Type: CommandTypeFullMatch, DMOnly: true}) registerCommand(Command{Trigger: "!mods", Output: "Bei Fragen, Problemen und Beschwerden wende dich bitte an die Moderatoren oder schick mir eine Nachricht beginnend mit !complain, um dich anonym zu beschweren.\nAktuell anwesende Mods werden dir rechts mit dem Rang „Maid“ angezeigt.", Type: CommandTypeFullMatch}) + // Features :Pog: + registerCommand(Command{Trigger: "!vc ", Type: CommandTypePrefix, Function: parseVoiceChannelCommand}) + // Admin and/or debug registerCommand(Command{Trigger: "<@%s> <3", Output: "<@%s> <3", Type: CommandTypeFullMatch, AdminOnly: true, OutputIsReply: true, RequiresMention: true}) registerCommand(Command{Trigger: "echo", Type: CommandTypePrefix, Function: echoMessage, AdminOnly: true}) diff --git a/voicechannel.go b/voicechannel.go new file mode 100644 index 0000000..b1df72b --- /dev/null +++ b/voicechannel.go @@ -0,0 +1,61 @@ +package main + +import ( + "fmt" + "github.com/bwmarrin/discordgo" + "log" + "strconv" + "strings" + "time" +) + +var tempChannels []*discordgo.Channel + +func parseVoiceChannelCommand(session *discordgo.Session, message *discordgo.MessageCreate) { + userLimit, err := strconv.Atoi(strings.Split(message.Content, " ")[1]) + if err != nil { + session.ChannelMessageSend(message.ChannelID, "Error: Expected a number after !vc") + log.Printf("Incorrect syntax for !vc, “%s” triggered by %s", message.Content, userToString(message.Author)) + return + } + if userLimit > 99 { + session.ChannelMessageSend(message.ChannelID, fmt.Sprintf("Als ob %d Leute *mit dir* in einen Channel wollen", userLimit-1)) + log.Printf("%s tried to create a channel with %d slots", userToString(message.Author), userLimit) + return + } + createData := discordgo.GuildChannelCreateData{ + Name: fmt.Sprintf("%s’s Volatile Corner", message.Author.Username), + Type: discordgo.ChannelTypeGuildVoice, + UserLimit: userLimit, + } + channel, err := session.GuildChannelCreateComplex(message.GuildID, createData) + if err != nil { + session.ChannelMessageSend(message.ChannelID, "Couldn’t create the voice channel. Please bug kageru about this.") + log.Printf("Failed to create voice channel, %s", err) + return + } + tempChannels = append(tempChannels, channel) + session.GuildMemberMove(config.ServerID, message.Author.ID, channel.ID) +} + +func checkAndDeleteUnusedChannels(session *discordgo.Session) { + for true { + time.Sleep(30 * time.Second) + for i, channel := range tempChannels { + if channelIsEmpty(channel.ID) { + session.ChannelDelete(channel.ID) + tempChannels = remove(tempChannels, i) + break + } + } + } +} + +func channelIsEmpty(channelID string) bool { + for _, voiceState := range getServer().VoiceStates { + if channelID == voiceState.ChannelID { + return false + } + } + return true +}