Compare commits

...

41 Commits

Author SHA1 Message Date
skeletable 36bb0b995f 4x multiplier 2022-09-28 22:41:44 +02:00
skeletable b765e5f7a3 reduce tickrate 2022-09-28 22:37:33 +02:00
skeletable ed465445b3 catch-up mechanics 2022-09-28 19:48:14 +02:00
skeletable 5652e85858 rebalance drop rates 2022-09-28 19:23:47 +02:00
skeletable 4f1e9ee33e :trolls: 2022-09-28 19:07:21 +02:00
skeletable 79d96d19d4 Merge branch 'candy' into 'master'
Merge branch 'master' into 'candy'

See merge request skeletable/flowers!7
2022-09-28 15:26:06 +00:00
skeletable 38edfb16c9 Merge branch 'master' into 'candy'
Master

See merge request skeletable/flowers!6
2022-09-28 15:25:07 +00:00
skeletable 8fb9a08346 Merge branch 'candy' into 'master'
# Conflicts:
#   main.go
2022-09-28 15:24:32 +00:00
skeletable 2b0f623aa6 better version info 2022-09-28 17:20:10 +02:00
skeletable d34443214d better version info 2022-09-28 17:16:05 +02:00
skeletable dfdfc95385 make claiming more responsive hopefully 2022-09-28 17:10:36 +02:00
skeletable 300ac93783 kornflake 2022-09-27 23:45:36 +02:00
skeletable e970479928 Merge branch 'master' into 'candy'
gundam

See merge request skeletable/flowers!4
2022-09-27 18:10:07 +00:00
skeletable d73bb37279 candy rank and tickrate fix 2022-09-27 19:49:51 +02:00
skeletable 554aeb9575 new candy 2022-09-27 18:15:12 +02:00
skeletable 9aa2ec506c tickrate limit reached 2022-09-27 17:48:54 +02:00
skeletable 15f4a6e6a3 adduser fix 2022-09-27 17:06:25 +02:00
skeletable 76751063a6 count buffs 2022-09-27 17:03:08 +02:00
skeletable 986cf3b4a2 deluser fix 2022-09-27 16:53:57 +02:00
skeletable 5a65afbce3 xorcon candy 2022-09-27 16:42:24 +02:00
skeletable 013ff5ffb1 candy counting 2022-09-27 16:26:06 +02:00
skeletable 6c9a47081f basic sql functions 2022-09-27 15:21:33 +02:00
skeletable e9af59d541 sqlite 2022-09-26 22:32:17 +02:00
skeletable 87e02c43a8 reaction blocklist 2022-09-25 18:38:13 +02:00
skeletable 54f85f3a7a increase polling rate 2022-09-25 13:15:03 +02:00
skeletable 456032a65b candy events 2022-09-25 13:01:14 +02:00
skeletable f3a36d0c56 milky candy effect 2022-09-24 19:27:11 +02:00
skeletable eb8cf5cd92 claiming 2022-09-24 19:14:11 +02:00
skeletable a4c920410f meta 2022-09-24 18:37:45 +02:00
skeletable cbcb1f8acd sad 2022-09-24 17:48:05 +02:00
skeletable 8e5fcf2462 candy variants 2022-09-24 16:53:52 +02:00
skeletable ba929293ae random candy 2022-09-24 16:46:25 +02:00
skeletable bf4debbca1 default candy 2022-09-24 16:02:28 +02:00
skeletable fb8c47dff9 candy loop fix 2022-09-24 15:51:29 +02:00
skeletable aed8ad2ac1 milky 2022-09-24 15:49:40 +02:00
skeletable b170e3eec5 captain britain 2022-09-24 15:37:21 +02:00
skeletable ef900ca3ce reactions 2022-09-24 15:25:33 +02:00
skeletable dd72849baf drop id 2022-09-24 15:17:38 +02:00
skeletable 223f33c79b drop id 2022-09-24 15:15:44 +02:00
skeletable 224c1ec80b reduce droprate 2022-09-24 15:10:44 +02:00
skeletable d3be3e1539 candywork 2022-09-24 14:46:55 +02:00
3 changed files with 474 additions and 3 deletions

5
go.mod
View File

@ -2,7 +2,10 @@ module inaba9000
go 1.17
require github.com/bwmarrin/discordgo v0.23.2
require (
github.com/bwmarrin/discordgo v0.23.2
github.com/mattn/go-sqlite3 v1.14.15
)
require (
github.com/gorilla/websocket v1.4.0 // indirect

2
go.sum
View File

@ -2,5 +2,7 @@ github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt
github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=

470
main.go
View File

@ -3,10 +3,12 @@ package main
import (
"bufio"
"bytes"
"database/sql"
"errors"
"fmt"
"io"
"io/ioutil"
"math"
"math/rand"
"os"
"os/exec"
@ -17,6 +19,7 @@ import (
"time"
"github.com/bwmarrin/discordgo"
_ "github.com/mattn/go-sqlite3"
)
// Variables used for command line parameters
@ -97,6 +100,142 @@ func getFortunes() []string {
// return getFortunes()[rand.Intn(len(getFortunes()))]
// }
func getCandyPic() string {
pics := []string{
"https://cdn.discordapp.com/attachments/956628829735125042/1023232603379212339/candyroland.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023238894742937650/candyphos.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023239554481799328/candynooo.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023240219287367750/candyhappy.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023242557670572052/candyclueless.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023242846490329138/candybased.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023243877429284874/candylol.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023243877676761108/candyjust.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023245477484953610/candykneel.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023245477875040336/candylfg.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023245478214766712/candythicc.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023245478504169552/candysaber.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023245478869078026/candythis.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023245479187841075/candy15.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1023259345934352414/candysad.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1024353063076642866/candynemorgal.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1024353428027211826/candyschizo.jpg",
"https://cdn.discordapp.com/attachments/956628829735125042/1024728955963588608/candytroll.jpg",
}
return pics[rand.Intn(len(pics))]
}
func candy(s *discordgo.Session, channel string) {
candy1 := &discordgo.MessageEmbed{
Title: "Candy",
Color: 0,
Footer: &discordgo.MessageEmbedFooter{
Text: "candy1",
},
Image: &discordgo.MessageEmbedImage{
URL: getCandyPic(),
},
}
candyRadmeal := &discordgo.MessageEmbed{
Title: "Candy",
Color: 0xff0000,
Footer: &discordgo.MessageEmbedFooter{
Text: "candyRadmeal",
},
Image: &discordgo.MessageEmbedImage{
URL: "https://cdn.discordapp.com/attachments/946859404819587162/946897683908542494/P10213-191951-1.jpg",
},
}
candyCaptain := &discordgo.MessageEmbed{
Title: "Captain Candy",
Color: 0xffe600,
Footer: &discordgo.MessageEmbedFooter{
Text: "candyCaptain",
},
Image: &discordgo.MessageEmbedImage{
URL: "https://cdn.discordapp.com/attachments/956628829735125042/1023225555820216440/unknown.png",
},
}
candyMilky := &discordgo.MessageEmbed{
Title: "Chocolate Inaba",
Color: 0x6df175,
Footer: &discordgo.MessageEmbedFooter{
Text: "candyMilky",
},
Image: &discordgo.MessageEmbedImage{
URL: "https://cdn.discordapp.com/attachments/956628829735125042/1023229123725893632/7c5085c86d4f230dc253c62b6266279f.jpg",
},
}
candyMeta := &discordgo.MessageEmbed{
Title: "Macaroons",
Color: 0xa90000,
Footer: &discordgo.MessageEmbedFooter{
Text: "candyMeta",
},
Image: &discordgo.MessageEmbedImage{
URL: "https://cdn.discordapp.com/attachments/956628829735125042/1023271248903544972/macaroon.jpg",
},
}
candyXorcon := &discordgo.MessageEmbed{
Title: "Xorconium Pills",
Color: 0x306AC0,
Footer: &discordgo.MessageEmbedFooter{
Text: "candyXorcon",
},
Image: &discordgo.MessageEmbedImage{
URL: "https://cdn.discordapp.com/attachments/956628829735125042/1024326522389147718/Alpha_Xorcon.png",
},
}
candyKornflake := &discordgo.MessageEmbed{
Title: "Candy Korn",
Color: 0xff5500,
Footer: &discordgo.MessageEmbedFooter{
Text: "candyKornflake",
},
Image: &discordgo.MessageEmbedImage{
URL: "https://cdn.discordapp.com/attachments/956628829735125042/1024436493495836762/kornflake.jpg",
},
}
candyKiko := &discordgo.MessageEmbed{
Title: "Kikola Cubes",
Color: 0x8f32a8,
Footer: &discordgo.MessageEmbedFooter{
Text: "candyKiko",
},
Image: &discordgo.MessageEmbedImage{
URL: "https://cdn.discordapp.com/attachments/956628829735125042/1024731407001591919/unknown.png",
},
}
drop := candy1
rand.Seed(time.Now().Unix())
switch rand.Intn(40) {
case 1, 2:
drop = candyCaptain
case 3, 4:
drop = candyMilky
case 5, 6:
drop = candyRadmeal
case 7:
drop = candyMeta
case 8, 9:
drop = candyXorcon
case 10, 11:
drop = candyKornflake
case 12, 13:
drop = candyKiko
default:
drop = candy1
}
ms := &discordgo.MessageSend{
Content: "🍬 ***Some candy has appeared! React to this message to claim it.*** 🍬",
Embed: drop,
}
s.ChannelMessageSendComplex(channel, ms)
}
func battle(user string, target string) string {
rand.Seed(time.Now().Unix())
userPower := int16(0)
@ -235,13 +374,170 @@ func getFiles() {
}
}
func initdb() {
file, err := os.Create("guilds.db")
if err != nil {
fmt.Println(err.Error())
return
}
file.Close()
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return
}
users_table := `CREATE TABLE users (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"userID" TEXT,
"candy" INT,
"buff" INT);`
query, err := db.Prepare(users_table)
if err != nil {
fmt.Println(err.Error())
return
}
query.Exec()
}
func addUser(userID string, candy int, buff int) {
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return
}
records := `INSERT INTO users(userID, candy, buff) VALUES (?, ?, ?)`
query, err := db.Prepare(records)
if err != nil {
fmt.Println(err.Error())
return
}
_, err = query.Exec(userID, candy, buff)
if err != nil {
fmt.Println(err.Error())
return
}
}
func delUser(userID string) {
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return
}
query, err := db.Prepare(`DELETE FROM users WHERE userID = ?`)
if err != nil {
fmt.Println(err.Error())
return
}
query.Exec()
}
func checkUser(userID string) bool {
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return false
}
err = db.QueryRow(`SELECT userID FROM users WHERE userID = ?`, userID).Scan(&userID)
if err != nil {
if err != sql.ErrNoRows {
fmt.Println(err.Error())
}
return false
}
return true
}
func checkUserCandy(userID string) int {
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return 0
}
var candy int
err = db.QueryRow(`SELECT candy FROM users WHERE userID = ?`, userID).Scan(&candy)
if err != nil {
fmt.Println(err.Error())
return 0
}
return candy
}
func addCandy(userID string, amount int) {
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return
}
query, err := db.Prepare(`UPDATE users SET candy = candy + ? WHERE userID = ?`)
_, err = query.Exec(amount, userID)
if err != nil {
fmt.Println(err.Error())
}
}
func addBuff(userID string, amount int) {
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return
}
query, err := db.Prepare(`UPDATE users SET buff = buff + ? WHERE userID = ?`)
_, err = query.Exec(amount, userID)
if err != nil {
fmt.Println(err.Error())
}
}
func candyRank() (string, error) {
ms := ""
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return ms, err
}
query, err := db.Query(`SELECT userID, candy FROM users ORDER BY candy DESC LIMIT 10`)
if err != nil {
fmt.Println(err.Error())
return ms, err
}
defer query.Close()
n := 1
for query.Next() {
var userID string
var candy int
query.Scan(&userID, &candy)
ms += fmt.Sprint(n) + `. <@` + userID + "> " + fmt.Sprint(candy) + "\n"
n++
}
return ms, err
}
func topUserCandy() (int, string) {
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return 0, ""
}
var candy int
var user string
err = db.QueryRow(`SELECT candy, userID FROM users WHERE candy = (SELECT MAX(candy) FROM users)`).Scan(&candy, &user)
if err != nil {
fmt.Println(err.Error())
return 0, ""
}
return candy, user
}
func main() {
commitID, err := exec.Command("git", "log", "-1", "--format=%h").Output()
commitID, err := exec.Command("git", "log", "--oneline", "-1").Output()
if err != nil {
fmt.Println("Error getting git commit ID: ", err)
}
flowerVer = string(commitID) + " \"Sapphire\""
flowerVer = `"Ghost Quartz"
Last commit:
` + string(commitID)
fmt.Println(flowerVer)
@ -253,6 +549,17 @@ func main() {
fmt.Println("Checking files.")
getFiles()
_, err = os.Stat("guilds.db")
if errors.Is(err, os.ErrNotExist) {
fmt.Println("Guilds database not found!")
fmt.Println("Initialising database...")
initdb()
fmt.Println("Testing database:")
addUser("0000000", 100, 0)
delUser("0000000")
fmt.Println("Test complete.")
}
// create a new discord session using the provided bot token.
dg, err := discordgo.New("Bot " + os.Args[1])
if err != nil {
@ -325,9 +632,117 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
// Ignore all messages created by the bot itself
// This isn't required in this specific example but it's a good practice.
var claimed bool
var tickrate time.Duration
const maxtickrate = 5000 * time.Millisecond
if m.Author.ID == s.State.User.ID {
if m.Content == "🍬 ***Some candy has appeared! React to this message to claim it.*** 🍬" {
s.MessageReactionAdd(m.ChannelID, m.Reference().MessageID, "🍬")
}
tickrate = 250 * time.Millisecond
claimed = false
for i := 0; i < 720; i++ {
reactions, err := s.MessageReactions(m.ChannelID, m.Reference().MessageID, "🍬", 2, "", "")
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
i -= 1
continue
}
if len(reactions) <= 1 {
continue
} else {
blocked := false
blockfile, err := ioutil.ReadFile("blocklist.txt")
if err != nil {
fmt.Println(err.Error())
}
blocklist := strings.Split(string(blockfile), "\n")
for _, j := range blocklist {
if j == reactions[0].ID && reactions[0].ID != "228911057316347905" {
blocked = true
s.MessageReactionRemove(m.ChannelID, m.Reference().MessageID, "🍬", j)
s.ChannelMessageSend(m.ChannelID, "1 blocked reaction")
i -= 1
k := 0
reactions = append(reactions[:k], reactions[k+1:]...)
blocked = false
}
}
if reactions[0].ID == s.State.User.ID {
i -= 1
continue
}
if blocked == false {
var candyvalue int
bufftype := "none"
buffvalue := 0
var candystr string
switch m.Embeds[0].Footer.Text {
case "candyMilky":
candyvalue = 500
bufftype = "tewi"
case "candyMeta":
candyvalue = 1000
case "candyCaptain":
candyvalue = 250
case "candyRadmeal":
candyvalue = -200
case "candyXorcon":
candyvalue = 50
bufftype = "alpha"
buffvalue = 1
case "candyKornflake":
candyvalue = 200
case "candyKiko":
candyvalue = 500
default:
candyvalue = 100
}
maxcandy, _ := topUserCandy()
multiplier := "(1x)"
if checkUserCandy(reactions[0].ID) < (maxcandy/4) {
multiplier = "(4x)"
candyvalue = candyvalue * 4
} else if checkUserCandy(reactions[0].ID) < (maxcandy/2) {
multiplier = "(2x)"
candyvalue = candyvalue * 2
}
if !math.Signbit(float64(candyvalue)) {
candystr = "+" + fmt.Sprint(candyvalue)
} else { candystr = fmt.Sprint(candyvalue) }
msg := reactions[0].Username + " has claimed the candy! (" + candystr + " 🍬) " + multiplier
switch bufftype {
case "tewi":
msg += "\n*Good luck!* Global candy droprate temporarily increased!"
case "alpha":
msg += "\n*Bash!* Crit chance permanently increased!"
}
if !checkUser(reactions[0].ID) {
addUser(reactions[0].ID, candyvalue, buffvalue)
} else {
addCandy(reactions[0].ID, candyvalue)
addBuff(reactions[0].ID, buffvalue)
}
s.ChannelMessageSend(m.ChannelID, msg)
claimed = true
}
if claimed { break }
}
time.Sleep(tickrate)
if tickrate < maxtickrate {
tickrate += 10 * time.Millisecond
}
if claimed { break }
}
return
}
rand.Seed(time.Now().Unix())
if rand.Intn(100) < 4 {
candy(s, m.ChannelID)
}
if strings.HasPrefix(m.Content, "pp!") {
blockfile, err := ioutil.ReadFile("blocklist.txt")
if err != nil {
@ -858,4 +1273,55 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
}
s.ChannelMessageSend(m.ChannelID, "Unblocked "+felon)
}
if m.Content == "insert candy" && m.Author.ID == "228911057316347905" {
candy(s, m.ChannelID)
}
if strings.HasPrefix(m.Content, "pp!db") && m.Author.ID == "228911057316347905" {
db, err := sql.Open("sqlite3", "guilds.db")
if err != nil {
fmt.Println(err.Error())
return
}
query, err := db.Prepare(parseArgs(m.Content))
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
return
}
query.Exec()
s.ChannelMessageSend(m.ChannelID, "OK")
}
if strings.HasPrefix(m.Content, "pp!candy") {
s.ChannelMessageSend(m.ChannelID, "Collected candy: " + fmt.Sprint(checkUserCandy(m.Author.ID)))
}
if strings.HasPrefix(m.Content, "pp!checkuser") {
s.ChannelMessageSend(m.ChannelID, fmt.Sprint(checkUser(m.Author.ID)))
}
if strings.HasPrefix(m.Content, "pp!rank") {
rank, err := candyRank()
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
return
}
ms := &discordgo.MessageSend{
Embed: &discordgo.MessageEmbed{
Title: "Candy ranking",
Description: rank,
},
AllowedMentions: &discordgo.MessageAllowedMentions{},
}
s.ChannelMessageSendComplex(m.ChannelID, ms)
}
if strings.HasPrefix(m.Content, "pp!top") {
candy, user := topUserCandy()
s.ChannelMessageSendComplex(m.ChannelID, &discordgo.MessageSend{
Content: "Most candy earned: <@" + user + "> " + fmt.Sprint(candy),
AllowedMentions: &discordgo.MessageAllowedMentions{},
})
}
}