122 lines
3.2 KiB
Go
122 lines
3.2 KiB
Go
package modules
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/bwmarrin/discordgo"
|
|
|
|
"TerraOceanBot/db"
|
|
"TerraOceanBot/discord/backend"
|
|
"TerraOceanBot/discord/config"
|
|
"TerraOceanBot/discord/message"
|
|
)
|
|
|
|
type confirmedResult struct {
|
|
VoteID int
|
|
IsPositive bool
|
|
}
|
|
|
|
const invalidVote = -1
|
|
|
|
var voteMutex sync.Mutex
|
|
var toAnnounceResultList []confirmedResult
|
|
|
|
func ListenToVoteFinishes(s *discordgo.Session) {
|
|
for {
|
|
voteMutex.Lock()
|
|
for _, v := range toAnnounceResultList {
|
|
if v.VoteID == invalidVote {
|
|
continue
|
|
}
|
|
message.AuditInfo(s, fmt.Sprintf("Announcing the result of vote %d.", v.VoteID))
|
|
if err := db.FinishVote(v.VoteID); err != nil {
|
|
message.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 {
|
|
message.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 {
|
|
message.AuditError(s, "", err)
|
|
return
|
|
}
|
|
currentScore += float64(vote.Value) * trust
|
|
totalTrust += float64(trust)
|
|
}
|
|
|
|
totalGlobalTrust, err := backend.GetTotalTrust(s)
|
|
if err != nil {
|
|
message.AuditError(s, "", err)
|
|
return
|
|
}
|
|
remainingTrust := totalGlobalTrust - totalTrust
|
|
lowestPossible := (currentScore + remainingTrust) / totalGlobalTrust
|
|
highestPossible := (currentScore + remainingTrust*5) / totalGlobalTrust
|
|
|
|
voteMutex.Lock()
|
|
defer voteMutex.Unlock()
|
|
if highestPossible <= 3.5 || absoluteRejectionVote {
|
|
//Rejection confirmed.
|
|
for _, v := range toAnnounceResultList {
|
|
if v.VoteID == id {
|
|
//It's already queued to be announced in the next announcement cycle.
|
|
return
|
|
}
|
|
}
|
|
message.AuditInfo(s, fmt.Sprintf("Rejection of vote ID %d has been confirmed.", id))
|
|
toAnnounceResultList = append(toAnnounceResultList, confirmedResult{
|
|
VoteID: id,
|
|
IsPositive: false,
|
|
})
|
|
} else if lowestPossible >= 3.5 {
|
|
//Acceptance confirmed.
|
|
for _, v := range toAnnounceResultList {
|
|
if v.VoteID == id {
|
|
//It's already queued to be announced in the next announcement cycle.
|
|
return
|
|
}
|
|
}
|
|
message.AuditInfo(s, fmt.Sprintf("Acceptance of vote ID %d has been confirmed.", id))
|
|
toAnnounceResultList = append(toAnnounceResultList, confirmedResult{
|
|
VoteID: id,
|
|
IsPositive: true,
|
|
})
|
|
} else {
|
|
//Nothing happened. Make sure it's not in the queue.
|
|
for k, v := range toAnnounceResultList {
|
|
if v.VoteID == id {
|
|
//It's already queued to be announced in the next announcement cycle.
|
|
toAnnounceResultList[k] = confirmedResult{
|
|
VoteID: invalidVote,
|
|
IsPositive: false,
|
|
}
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|