diff --git a/GoBot/db.go b/GoBot/db.go index 476af1d..d027177 100644 --- a/GoBot/db.go +++ b/GoBot/db.go @@ -31,4 +31,8 @@ func init() { if err != nil { panic(err) } + _, err = db.Exec("CREATE TABLE IF NOT EXISTS trustVote (sourceUser INTEGER, targetUser INTEGER, trust INTEGER, UNIQUE(sourceUser, targetUser))") + if err != nil { + panic(err) + } } diff --git a/GoBot/db_trust.go b/GoBot/db_trust.go new file mode 100644 index 0000000..386f42e --- /dev/null +++ b/GoBot/db_trust.go @@ -0,0 +1,23 @@ +package main + +import "errors" + +var errForceRejectionOnApprovedPerson = errors.New("db: attempt to force reject a user that is already approved") + +func getTrustVote(targetID string) ([]int, error) { + rows, err := db.Query("SELECT trust FROM trustVote WHERE targetUser=?", targetID) + if err != nil { + return nil, err + } + + defer rows.Close() + + array := make([]int, 0) + for rows.Next() { + var trust int + rows.Scan(&trust) + array = append(array, trust) + } + + return array, nil +} diff --git a/GoBot/trust.go b/GoBot/trust.go index b7eea49..08198aa 100644 --- a/GoBot/trust.go +++ b/GoBot/trust.go @@ -1,11 +1,58 @@ package main -func getTrust(discordID string) int { - //TODO This is a stub. Everyone has same weight for now. - return 1 +import "github.com/bwmarrin/discordgo" + +var trustCache map[string]float64 + +func getTrust(discordID string) (float64, error) { + if v, ok := trustCache[discordID]; ok { + return v, nil + } + votes, err := getTrustVote(discordID) + if err != nil { + return 0.0, err + } + votes = append(votes, 3) + var total float64 + for _, v := range votes { + total += float64(v) + } + return total / float64(len(votes)), nil +} + +func getTotalTrust(s *discordgo.Session) (float64, error) { + members, err := getAllMembers(s) + if err != nil { + return 0.0, err + } + var total float64 + for _, member := range members { + trust, err := getTrust(member.User.ID) + if err != nil { + return 0.0, err + } + total += trust + } + return total, nil } -func getTotalTrust() int { - //TODO This is a stub. It returns 1 for easier testing for now. - return 1 +func getAllMembers(s *discordgo.Session) ([]*discordgo.Member, error) { + initial, err := s.GuildMembers(guildID, "", 1000) + if err != nil { + return nil, err + } + next := initial[len(initial)-1].User.ID + for next != "" { + nextArray, err := s.GuildMembers(guildID, next, 1000) + if err != nil { + return nil, err + } + if len(nextArray) == 0 { + next = "" + } else { + next = nextArray[len(nextArray)-1].User.ID + initial = append(initial, nextArray...) + } + } + return initial, nil } diff --git a/GoBot/vote_result.go b/GoBot/vote_result.go index 00cdb45..634b3b9 100644 --- a/GoBot/vote_result.go +++ b/GoBot/vote_result.go @@ -53,13 +53,23 @@ func checkForVoteResult(s *discordgo.Session, id int) { if vote.Value == forceRejectionVote { absoluteRejectionVote = true } - currentScore += float64(vote.Value * getTrust(vote.UserID)) - totalTrust += float64(getTrust(vote.UserID)) + trust, err := getTrust(vote.UserID) + if err != nil { + auditLog(s, fmt.Sprintf("Error while getting vote trust for user ID %d: %s", vote.UserID, err.Error())) + return + } + currentScore += float64(vote.Value) * trust + totalTrust += float64(trust) } - remainingTrust := float64(getTotalTrust()) - totalTrust - lowestPossible := (currentScore + remainingTrust) / float64(getTotalTrust()) - highestPossible := (currentScore + remainingTrust*5) / float64(getTotalTrust()) + totalGlobalTrust, err := getTotalTrust(s) + if err != nil { + auditLog(s, fmt.Sprintf("Error while getting total vote trust: %s", err.Error())) + return + } + remainingTrust := totalGlobalTrust - totalTrust + lowestPossible := (currentScore + remainingTrust) / totalGlobalTrust + highestPossible := (currentScore + remainingTrust*5) / totalGlobalTrust if highestPossible <= 3.5 || absoluteRejectionVote { //Rejection confirmed.