gacha: Implement permission giving

master 0.3
Luther Wen Xu 2019-11-18 22:38:03 +07:00
parent 38a9d2eda2
commit 614186a4a7
Signed by: chanbakjsd
GPG Key ID: B7D77E3E9D102B70
6 changed files with 163 additions and 18 deletions

20
db.go

@ -0,0 +1,20 @@
package main
import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
)
var db *sql.DB
func init() {
var err error
db, err = sql.Open("sqlite3", "./bot.db")
if err != nil {
panic(err)
}
db.SetMaxOpenConns(1)
db.Exec("CREATE TABLE xp(id STRING NOT NULL UNIQUE, xp INTEGER NOT NULL)")
db.Exec("CREATE TABLE shard(id STRING NOT NULL UNIQUE, shard INTEGER NOT NULL)")
}

@ -0,0 +1,85 @@
package main
import (
"crypto/rand"
"fmt"
"github.com/bwmarrin/discordgo"
)
const (
viewAuditLogRole = "645856347258093568"
manageWebhookRole = "645856081750523914"
changeNicknameRole = "645977231281356800"
embedLinkRole = "645977361254318080"
voiceActivityRole = "645977361254318080"
)
func checkForGachaEligibility(dg *discordgo.Session, discordID, intendedLevel string) {
member, err := dg.GuildMember(guildID, discordID)
if err != nil {
logError(dg, "checkForGachaEligibility", "getGuildMember", discordID)
return
}
found := false
for _, v := range member.Roles {
if v == intendedLevel {
found = true
break
}
}
if found {
return
}
rollGacha(dg, member)
err = dg.GuildMemberRoleAdd(guildID, discordID, intendedLevel)
if err != nil {
logError(dg, "checkForGachaEligibility", "guildMemberRoleAdd", err)
}
}
func rollGacha(dg *discordgo.Session, member *discordgo.Member) {
lookUpAndGive := func(friendlyName, role string) {
found := false
for _, v := range member.Roles {
if v == role {
found = true
break
}
}
channel, err := dg.UserChannelCreate(member.User.ID)
if found {
rewardShard(dg, member.User.ID)
if err == nil {
dg.ChannelMessageSend(
channel.ID,
fmt.Sprintf(
"**GACHA > ** You got __%s__! However, it was a duplicate so you got a shard instead.", friendlyName,
),
)
}
} else {
dg.GuildMemberRoleAdd(guildID, member.User.ID, role)
dg.ChannelMessageSend(
channel.ID,
fmt.Sprintf("**GACHA > ** You got __%s__!", friendlyName),
)
}
}
gachaRandomness := make([]byte, 1)
rand.Read(gachaRandomness)
switch gachaRandomness[0] % 5 {
case 0:
lookUpAndGive("View Audit Log", viewAuditLogRole)
case 1:
lookUpAndGive("Manage Webhook", manageWebhookRole)
case 2:
lookUpAndGive("Change Nickname", changeNicknameRole)
case 3:
lookUpAndGive("Embed Link", embedLinkRole)
case 4:
lookUpAndGive("Use Voice Activity", voiceActivityRole)
}
}

@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"strings" "strings"
"sync" "sync"
@ -17,7 +18,7 @@ var assignedLevels = make(map[string]int)
var rolesFromLevel []string var rolesFromLevel []string
func init() { func init() {
levels, _ := ioutil.ReadFile("levels.txt") levels, _ := ioutil.ReadFile("roles.txt")
rolesFromLevel = strings.Split(string(levels), "\n") rolesFromLevel = strings.Split(string(levels), "\n")
for k, v := range rolesFromLevel { for k, v := range rolesFromLevel {
rolesFromLevel[k] = strings.TrimSpace(v) rolesFromLevel[k] = strings.TrimSpace(v)
@ -32,6 +33,7 @@ func addToLevelQueue(discordID string) {
func listenToLevelUpdate(dg *discordgo.Session) { func listenToLevelUpdate(dg *discordgo.Session) {
for { for {
time.Sleep(5 * time.Second)
levelMutex.Lock() levelMutex.Lock()
for k, v := range levelQueue { for k, v := range levelQueue {
if !v { if !v {
@ -41,13 +43,9 @@ func listenToLevelUpdate(dg *discordgo.Session) {
level, _ := getLevelAndXP(dg, k) level, _ := getLevelAndXP(dg, k)
if assignedLevels[k] != level { if assignedLevels[k] != level {
assignedLevels[k] = level assignedLevels[k] = level
err := dg.GuildMemberRoleAdd(guildID, k, rolesFromLevel[level-1]) go checkForGachaEligibility(dg, k, rolesFromLevel[level-1])
if err != nil {
logError(dg, "assignlevel", err)
}
} }
} }
levelMutex.Unlock() levelMutex.Unlock()
time.Sleep(5 * time.Second)
} }
} }

@ -12,9 +12,12 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
} }
go incrementXP(s, m.Author.ID) go incrementXP(s, m.Author.ID)
if m.Content == "p!level" { if m.Content == "pgqlevel" {
handleXPRequest(s, m) handleXPRequest(s, m)
} }
if m.Content == "pgqshard" {
handleShardRequest(s, m)
}
} }
func handleXPRequest(s *discordgo.Session, m *discordgo.MessageCreate) { func handleXPRequest(s *discordgo.Session, m *discordgo.MessageCreate) {
@ -31,3 +34,14 @@ func handleXPRequest(s *discordgo.Session, m *discordgo.MessageCreate) {
), ),
) )
} }
func handleShardRequest(s *discordgo.Session, m *discordgo.MessageCreate) {
shard := getShard(s, m.Author.ID)
s.ChannelMessageSend(
m.ChannelID,
fmt.Sprintf(
"<@%s> has %d shards.",
m.Author.ID, shard,
),
)
}

@ -0,0 +1,39 @@
package main
import (
"github.com/bwmarrin/discordgo"
)
func rewardShard(dg *discordgo.Session, discordID string) {
tx, err := db.Begin()
if err != nil {
logError(dg, "rewardShard", "begin", discordID, err)
return
}
_, err = tx.Exec("INSERT INTO shard(id, shard) VALUES(?, 1) ON CONFLICT(id) DO UPDATE SET shard = shard+1;", discordID)
if err != nil {
logError(dg, "rewardShard", "insert", discordID, err)
tx.Rollback()
return
}
err = tx.Commit()
if err != nil {
logError(dg, "rewardShard", "commit", discordID, err)
return
}
}
func getShard(dg *discordgo.Session, discordID string) int {
rows, err := db.Query("SELECT shard FROM shard WHERE id=?", discordID)
if err != nil {
logError(dg, "getShard", "select", discordID, err)
return 0
}
defer rows.Close()
if rows.Next() {
var shard int
rows.Scan(&shard)
return shard
}
return 0
}

11
xp.go

@ -1,29 +1,18 @@
package main package main
import ( import (
"database/sql"
"math" "math"
"sync" "sync"
"time" "time"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
_ "github.com/mattn/go-sqlite3"
) )
var db *sql.DB
var lastMessage = make(map[string]time.Time) var lastMessage = make(map[string]time.Time)
var incrementMutex = sync.Mutex{} var incrementMutex = sync.Mutex{}
var levelUpRequirementCache [30]int var levelUpRequirementCache [30]int
func init() { func init() {
var err error
db, err = sql.Open("sqlite3", "./bot.db")
if err != nil {
panic(err)
}
db.SetMaxOpenConns(1)
db.Exec("CREATE TABLE xp(id STRING NOT NULL UNIQUE, xp INTEGER NOT NULL)")
for i := 1; i <= 30; i++ { for i := 1; i <= 30; i++ {
//Constructed on Desmos: //Constructed on Desmos:
//y=2^{\frac{x}{3}}+.1x^{2}+1.2x-1 //y=2^{\frac{x}{3}}+.1x^{2}+1.2x-1