prestige: Implement prestige command

master 0.4
Luther Wen Xu 2019-11-19 14:59:32 +07:00
parent a11d9c94d2
commit fd8ad961b2
Signed by: chanbakjsd
GPG Key ID: B7D77E3E9D102B70
4 changed files with 140 additions and 4 deletions

@ -17,4 +17,5 @@ func init() {
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)")
db.Exec("CREATE TABLE prestige(id STRING NOT NULL UNIQUE, multiplier INTEGER NOT NULL)")
}

@ -2,11 +2,16 @@ package main
import (
"fmt"
"math"
"time"
"github.com/bwmarrin/discordgo"
)
const generalChannelID = "645550570001924098"
const emojiCheck = "✅"
var prestigeList = make(map[string]string)
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.Bot {
@ -20,6 +25,9 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Content == "pgqshard" {
handleShardRequest(s, m)
}
if m.Content == "pgqprestige" {
handlePrestigeRequest(s, m)
}
}
func handleXPRequest(s *discordgo.Session, m *discordgo.MessageCreate) {
@ -47,3 +55,61 @@ func handleShardRequest(s *discordgo.Session, m *discordgo.MessageCreate) {
),
)
}
func handlePrestigeRequest(s *discordgo.Session, m *discordgo.MessageCreate) {
currentPrestigeLevel := getPrestige(s, m.Author.ID)
xp := getXP(s, m.Author.ID)
newPrestigeLevel := xp/130000 + 1
if xp < levelUpRequirementCache[4] && currentPrestigeLevel == 1 {
s.ChannelMessageSend(m.ChannelID, "**PRESTIGE > **Prestige is only unlocked after level 5!")
return
}
var lowerLevelWarning string
if newPrestigeLevel <= currentPrestigeLevel {
lowerLevelWarning = "**WARNING: Your new prestige multiplier is NOT higher than your current prestige multiplier."
}
nearestPowerOfTen := math.Pow10(int(math.Floor(math.Log10(float64(newPrestigeLevel)))))
nextNearestLogicalPrestige := int((math.Floor(float64(newPrestigeLevel)/nearestPowerOfTen) + 1) * nearestPowerOfTen)
msg, err := s.ChannelMessageSend(
m.ChannelID,
fmt.Sprintf(
"<@%s>, here's your prestige multiplier:\n**Now: **__%dx__\n**New: **__%dx__\n**Next: **__%dx__ [%.1f%%]\n%s\n"+
"React with :white_check_mark: to proceed with prestiging.",
m.Author.ID,
currentPrestigeLevel,
newPrestigeLevel,
nextNearestLogicalPrestige, float64(xp)/float64(130000*(nextNearestLogicalPrestige-1))*100,
lowerLevelWarning,
),
)
if err != nil {
logError(s, "handlePrestigeRequest", "send", err)
return
}
prestigeList[msg.ID] = m.Author.ID
err = s.MessageReactionAdd(msg.ChannelID, msg.ID, emojiCheck)
if err != nil {
logError(s, "handlePrestigeRequest", "addReaction", err)
return
}
go func() {
time.Sleep(15 * time.Second)
err = s.MessageReactionsRemoveAll(msg.ChannelID, msg.ID)
if err != nil {
logError(s, "handlePrestigeRequest", "removeReaction", err)
}
}()
}
func checkPrestigeReact(s *discordgo.Session, m *discordgo.MessageReactionAdd) {
if prestigeList[m.MessageID] != m.UserID {
return
}
xp := getXP(s, m.UserID)
newPrestigeLevel := xp/130000 + 1
setPrestige(s, m.UserID, newPrestigeLevel)
s.ChannelMessageSend(m.ChannelID, "**PRESTIGE > ** <@%s>, you have prestiged!")
}

@ -0,0 +1,64 @@
package main
import (
"sync"
"github.com/bwmarrin/discordgo"
)
var prestigeCache = make(map[string]int)
var prestigeMutex = sync.Mutex{}
func setPrestige(dg *discordgo.Session, discordID string, newMultiplier int) {
prestigeMutex.Lock()
defer prestigeMutex.Unlock()
tx, err := db.Begin()
if err != nil {
logError(dg, "setPrestige", "begin", discordID, newMultiplier, err)
return
}
_, err = tx.Exec("REPLACE INTO prestige(id, multiplier) VALUES(?,?)", discordID, newMultiplier)
if err != nil {
logError(dg, "setPrestige", "insertMultiplier", discordID, newMultiplier, err)
tx.Rollback()
return
}
_, err = tx.Exec("REPLACE INTO xp(id, xp) VALUES(?,0)", discordID)
err = tx.Commit()
if err != nil {
logError(dg, "setPrestige", "insertXP", discordID, newMultiplier, err)
tx.Rollback()
return
}
if err != nil {
logError(dg, "setPrestige", "commit", discordID, newMultiplier, err)
return
}
prestigeCache[discordID] = newMultiplier
}
func getPrestige(dg *discordgo.Session, discordID string) int {
prestigeMutex.Lock()
defer prestigeMutex.Unlock()
if prestigeCache[discordID] > 0 {
return prestigeCache[discordID]
}
rows, err := db.Query("SELECT multiplier FROM prestige WHERE id=?", discordID)
if err != nil {
logError(dg, "getPrestige", "select", discordID, err)
return 0
}
defer rows.Close()
if rows.Next() {
var multiplier int
rows.Scan(&multiplier)
prestigeCache[discordID] = multiplier
return multiplier
}
prestigeCache[discordID] = 1
return 1
}

13
xp.go

@ -28,6 +28,7 @@ func incrementXP(dg *discordgo.Session, discordID string, inGeneral bool) {
if !inGeneral {
amountToIncrement /= notInGeneralNerf
}
amountToIncrement *= getPrestige(dg, discordID)
tx, err := db.Begin()
if err != nil {
@ -48,19 +49,23 @@ func incrementXP(dg *discordgo.Session, discordID string, inGeneral bool) {
addToLevelQueue(discordID)
}
func getLevelAndXP(dg *discordgo.Session, discordID string) (int, int) {
func getXP(dg *discordgo.Session, discordID string) int {
rows, err := db.Query("SELECT xp FROM xp WHERE id=?", discordID)
if err != nil {
logError(dg, "getLevelAndXP", "select", discordID, err)
return 1, 0
return 0
}
defer rows.Close()
if rows.Next() {
var xp int
rows.Scan(&xp)
return convertXPIntoLevel(xp)
return xp
}
return 1, 0
return 0
}
func getLevelAndXP(dg *discordgo.Session, discordID string) (int, int) {
return convertXPIntoLevel(getXP(dg, discordID))
}
func calculateIncrement(discordID string) int {