From e180dec331b759349e7eab5a2f472be68050fd76 Mon Sep 17 00:00:00 2001 From: Luther Wen Xu Date: Mon, 14 Oct 2019 18:01:25 +0800 Subject: [PATCH] go: Unify react implementation --- GoBot/discord/discord.go | 4 +-- GoBot/discord/modules/invite.go | 40 ++++++++++------------ GoBot/discord/modules/minecraft.go | 23 +++++-------- GoBot/discord/modules/react.go | 53 ++++++++++++++++++++++++++++++ GoBot/discord/modules/trust.go | 22 +++++-------- 5 files changed, 88 insertions(+), 54 deletions(-) create mode 100644 GoBot/discord/modules/react.go diff --git a/GoBot/discord/discord.go b/GoBot/discord/discord.go index ad0efea..9b18d5c 100644 --- a/GoBot/discord/discord.go +++ b/GoBot/discord/discord.go @@ -17,10 +17,8 @@ func StartBot(token string, kill chan bool) { } dg.AddHandler(ProcessCommand) + dg.AddHandler(modules.CheckForReact) dg.AddHandler(modules.CheckForVote) - dg.AddHandler(modules.CheckForTrustUpdate) - dg.AddHandler(modules.CheckForInvite) - dg.AddHandler(modules.ConfirmMinecraftUsername) if err := dg.Open(); err != nil { panic(err) diff --git a/GoBot/discord/modules/invite.go b/GoBot/discord/modules/invite.go index 8f28e72..1e09c6f 100644 --- a/GoBot/discord/modules/invite.go +++ b/GoBot/discord/modules/invite.go @@ -12,8 +12,6 @@ import ( "TerraOceanBot/server" ) -var pendingInviteConfirmation = make(map[string]invite) - type invite struct { User string Reason string @@ -106,10 +104,15 @@ var checkUseInvite = enforceDM(memberFilter(false, enforceArgumentCount( message.AuditErrorPM(s, m.ChannelID, err) return } - pendingInviteConfirmation[msg.ID] = invite{ - User: m.Author.ID, - Reason: command[2], - } + queueForReact( + msg.ID, + []string{emojiCheck, emojiX}, + invite{ + User: m.Author.ID, + Reason: command[2], + }, + inviteCallback, + ) s.MessageReactionAdd(channel.ID, msg.ID, emojiCheck) s.MessageReactionAdd(channel.ID, msg.ID, emojiX) message.InitNewEmbed(config.SuccessTitle, config.ValidateSuccess, config.SuccessColour). @@ -117,19 +120,9 @@ var checkUseInvite = enforceDM(memberFilter(false, enforceArgumentCount( }, ))) -func CheckForInvite(s *discordgo.Session, r *discordgo.MessageReactionAdd) { - if r.UserID == s.State.User.ID { - return - } - - invite, ok := pendingInviteConfirmation[r.MessageID] - if !ok { - return - } - delete(pendingInviteConfirmation, r.MessageID) - - switch r.Emoji.Name { - case emojiX: +func inviteCallback(s *discordgo.Session, r *discordgo.MessageReactionAdd, info interface{}) { + invite := info.(invite) + if r.Emoji.Name == emojiX { message.InitNewEmbed( config.ValidateConfirmationRejectCreatorTitle, config.ValidateConfirmationRejectCreatorDescription, @@ -141,9 +134,6 @@ func CheckForInvite(s *discordgo.Session, r *discordgo.MessageReactionAdd) { config.ErrorColour, ).SendPM(s, invite.User) return - case emojiCheck: - default: - return } message.InitNewEmbed( @@ -157,7 +147,11 @@ func CheckForInvite(s *discordgo.Session, r *discordgo.MessageReactionAdd) { config.ErrorColour, ).SendPM(s, invite.User) - msg, err := s.ChannelMessageSend(config.VoteChannel, "正在准备新的一个投票…… Preparing for the next vote...") + msg, err := message.InitNewEmbed( + config.VoteSuggestionUpcomingTitle, + config.VoteSuggestionUpcomingDescription, + config.VoteSuggestionUpcomingColour, + ).Send(s, config.VoteChannel) if err != nil { message.AuditErrorPM(s, r.UserID, err) return diff --git a/GoBot/discord/modules/minecraft.go b/GoBot/discord/modules/minecraft.go index 66c21ea..68c96e8 100644 --- a/GoBot/discord/modules/minecraft.go +++ b/GoBot/discord/modules/minecraft.go @@ -10,8 +10,6 @@ import ( "TerraOceanBot/server" ) -var minecraftConfirmReact = make(map[string]string) - var updateMinecraftUsername = memberFilter(true, enforceArgumentCount( config.SetMCUsernameUsage, 2, func(s *discordgo.Session, m *discordgo.MessageCreate, command []string) { @@ -39,23 +37,19 @@ var updateMinecraftUsername = memberFilter(true, enforceArgumentCount( if err != nil { message.AuditError(s, m.ChannelID, err) } - minecraftConfirmReact[msg.ID] = command[1] + queueForReact( + msg.ID, + []string{emojiCheck, emojiX}, + command[1], + confirmMinecraftUsername, + ) s.MessageReactionAdd(msg.ChannelID, msg.ID, emojiCheck) s.MessageReactionAdd(msg.ChannelID, msg.ID, emojiX) }, )) -func ConfirmMinecraftUsername(s *discordgo.Session, r *discordgo.MessageReactionAdd) { - if r.UserID == s.State.User.ID { - return - } - - newUsername, ok := minecraftConfirmReact[r.MessageID] - if !ok { - return - } - - delete(minecraftConfirmReact, r.MessageID) +func confirmMinecraftUsername(s *discordgo.Session, r *discordgo.MessageReactionAdd, info interface{}) { + newUsername := info.(string) switch r.Emoji.Name { case emojiCheck: @@ -86,6 +80,7 @@ func processUsernameUpdate(s *discordgo.Session, discordID, channelID, newUserna backend.UpdateVoiceChannelState(s) if oldErr == nil { server.WhitelistRemove(oldUsername) + server.DisconnectUser(oldUsername) } message.InitNewEmbed( diff --git a/GoBot/discord/modules/react.go b/GoBot/discord/modules/react.go new file mode 100644 index 0000000..ff81c7c --- /dev/null +++ b/GoBot/discord/modules/react.go @@ -0,0 +1,53 @@ +package modules + +import ( + "sync" + + "github.com/bwmarrin/discordgo" +) + +var reactLock sync.Mutex +var reactCallbacks = make(map[string]reactEntry) + +type reactCallback func(s *discordgo.Session, react *discordgo.MessageReactionAdd, info interface{}) +type reactEntry struct { + acceptedEmoji []string + callback reactCallback + info interface{} +} + +func queueForReact(messageID string, acceptedEmoji []string, info interface{}, callback reactCallback) { + reactLock.Lock() + defer reactLock.Unlock() + + reactCallbacks[messageID] = reactEntry{ + acceptedEmoji: acceptedEmoji, + callback: callback, + info: info, + } +} + +func CheckForReact(s *discordgo.Session, r *discordgo.MessageReactionAdd) { + entry, ok := reactCallbacks[r.MessageID] + if !ok { + return + } + + reactLock.Lock() + foundEmoji := false + for _, v := range entry.acceptedEmoji { + if r.Emoji.Name == v { + foundEmoji = true + break + } + } + if !foundEmoji { + reactLock.Unlock() + return + } + + delete(reactCallbacks, r.MessageID) + reactLock.Unlock() + + entry.callback(s, r, entry.info) +} diff --git a/GoBot/discord/modules/trust.go b/GoBot/discord/modules/trust.go index 905913d..73a5c67 100644 --- a/GoBot/discord/modules/trust.go +++ b/GoBot/discord/modules/trust.go @@ -9,8 +9,6 @@ import ( "TerraOceanBot/discord/message" ) -var trustMessage = make(map[string]string) - var changeTrust = enforceDM(memberFilter(true, enforceArgumentCount( config.ChangeTrustUsage, 2, func(s *discordgo.Session, m *discordgo.MessageCreate, command []string) { @@ -44,7 +42,12 @@ var changeTrust = enforceDM(memberFilter(true, enforceArgumentCount( return } - trustMessage[msg.ID] = member.User.ID + queueForReact( + msg.ID, + []string{emojiOne, emojiTwo, emojiThree, emojiFour, emojiFive, emojiCheck}, + member.User.ID, + trustCallback, + ) s.MessageReactionAdd(m.ChannelID, msg.ID, emojiOne) s.MessageReactionAdd(m.ChannelID, msg.ID, emojiTwo) @@ -55,17 +58,8 @@ var changeTrust = enforceDM(memberFilter(true, enforceArgumentCount( }, ))) -func CheckForTrustUpdate(s *discordgo.Session, r *discordgo.MessageReactionAdd) { - if r.UserID == s.State.User.ID { - return - } - target, ok := trustMessage[r.MessageID] - - if !ok { - return - } - - delete(trustMessage, r.MessageID) +func trustCallback(s *discordgo.Session, r *discordgo.MessageReactionAdd, info interface{}) { + target := info.(string) var value int switch r.Emoji.Name {