package modules import ( "fmt" "sync" "time" "github.com/bwmarrin/discordgo" "TerraOceanBot/db" "TerraOceanBot/discord/backend" "TerraOceanBot/discord/config" ) type confirmedResult struct { VoteID int IsPositive bool } var voteMutex sync.Mutex var toAnnounceResultList []confirmedResult func ListenToVoteFinishes(s *discordgo.Session) { for { voteMutex.Lock() for _, v := range toAnnounceResultList { auditInfo(s, fmt.Sprintf("Announcing the result of vote %d.", v.VoteID)) if err := db.FinishVote(v.VoteID); err != nil { auditError(s, "", err) continue } voteType, _ := db.GetVoteType(v.VoteID) voteName, _ := db.GetVoteName(v.VoteID) messageID, _ := db.GetMessageIDFromVote(v.VoteID) voteTypes[voteType].EmbedBuilder(v.VoteID, voteName).UpdateVoteStatus(v.IsPositive).Edit(s, config.VoteChannel, messageID) voteTypes[voteType].ResultHandler(s, v.VoteID, voteName, v.IsPositive) } toAnnounceResultList = toAnnounceResultList[:0] voteMutex.Unlock() time.Sleep(60 * time.Second) } } func checkForVoteResult(s *discordgo.Session, id int) { votes, err := db.GetAllVoteChoices(id) if err != nil { auditError(s, "", err) return } var currentScore, totalTrust float64 var absoluteRejectionVote bool for _, vote := range votes { if vote.Value == db.ForceRejectionVote { absoluteRejectionVote = true } trust, err := backend.GetTrust(s, vote.UserID) if err != nil { auditError(s, "", err) return } currentScore += float64(vote.Value) * trust totalTrust += float64(trust) } totalGlobalTrust, err := backend.GetTotalTrust(s) if err != nil { auditError(s, "", err) return } remainingTrust := totalGlobalTrust - totalTrust lowestPossible := (currentScore + remainingTrust) / totalGlobalTrust highestPossible := (currentScore + remainingTrust*5) / totalGlobalTrust if highestPossible <= 3.5 || absoluteRejectionVote { //Rejection confirmed. voteMutex.Lock() for _, v := range toAnnounceResultList { if v.VoteID == id { //It's already queued to be announced in the next announcement cycle. voteMutex.Unlock() return } } auditInfo(s, fmt.Sprintf("Rejection of vote ID %d has been confirmed.", id)) toAnnounceResultList = append(toAnnounceResultList, confirmedResult{ VoteID: id, IsPositive: false, }) voteMutex.Unlock() } if lowestPossible >= 3.5 { //Acceptance confirmed. voteMutex.Lock() for _, v := range toAnnounceResultList { if v.VoteID == id { //It's already queued to be announced in the next announcement cycle. voteMutex.Unlock() return } } auditInfo(s, fmt.Sprintf("Acceptance of vote ID %d has been confirmed.", id)) toAnnounceResultList = append(toAnnounceResultList, confirmedResult{ VoteID: id, IsPositive: true, }) voteMutex.Unlock() } }