fixes, stats removal
- Fixed opening Discord connection for Bots. - Fixed a lot of bad code syntax - seriously, this has to be their first project with Go. - Added some placeholder comments for golint to shut up. - Removed unnecessary code for redis stats - less library requirements, Yay!
This commit is contained in:
@@ -18,24 +18,21 @@ import (
|
|||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
redis "gopkg.in/redis.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// discordgo session
|
// discordgo session
|
||||||
discord *discordgo.Session
|
discord *discordgo.Session
|
||||||
|
|
||||||
// Redis client connection (used for stats)
|
|
||||||
rcli *redis.Client
|
|
||||||
|
|
||||||
// Map of Guild id's to *Play channels, used for queuing and rate-limiting guilds
|
// Map of Guild id's to *Play channels, used for queuing and rate-limiting guilds
|
||||||
queues map[string]chan *Play = make(map[string]chan *Play)
|
queues = make(map[string]chan *Play)
|
||||||
|
|
||||||
// Sound encoding settings
|
// bitrate Sound encoding settings
|
||||||
BITRATE = 128
|
bitrate = 128
|
||||||
MAX_QUEUE_SIZE = 6
|
// maxQueueSize Sound encoding settings
|
||||||
|
maxQueueSize = 6
|
||||||
|
|
||||||
// Owner
|
// OWNER variable
|
||||||
OWNER string
|
OWNER string
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,6 +50,7 @@ type Play struct {
|
|||||||
Forced bool
|
Forced bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SoundCollection of Sounds
|
||||||
type SoundCollection struct {
|
type SoundCollection struct {
|
||||||
Prefix string
|
Prefix string
|
||||||
Commands []string
|
Commands []string
|
||||||
@@ -76,8 +74,8 @@ type Sound struct {
|
|||||||
buffer [][]byte
|
buffer [][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array of all the sounds we have
|
// AIRHORN Array of all the sounds we have
|
||||||
var AIRHORN *SoundCollection = &SoundCollection{
|
var AIRHORN = &SoundCollection{
|
||||||
Prefix: "airhorn",
|
Prefix: "airhorn",
|
||||||
Commands: []string{
|
Commands: []string{
|
||||||
"!airhorn",
|
"!airhorn",
|
||||||
@@ -100,7 +98,8 @@ var AIRHORN *SoundCollection = &SoundCollection{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var KHALED *SoundCollection = &SoundCollection{
|
// KHALED collection
|
||||||
|
var KHALED = &SoundCollection{
|
||||||
Prefix: "another",
|
Prefix: "another",
|
||||||
ChainWith: AIRHORN,
|
ChainWith: AIRHORN,
|
||||||
Commands: []string{
|
Commands: []string{
|
||||||
@@ -114,7 +113,8 @@ var KHALED *SoundCollection = &SoundCollection{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var CENA *SoundCollection = &SoundCollection{
|
// CENA collection
|
||||||
|
var CENA = &SoundCollection{
|
||||||
Prefix: "jc",
|
Prefix: "jc",
|
||||||
Commands: []string{
|
Commands: []string{
|
||||||
"!johncena",
|
"!johncena",
|
||||||
@@ -130,7 +130,8 @@ var CENA *SoundCollection = &SoundCollection{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var ETHAN *SoundCollection = &SoundCollection{
|
// ETHAN collection
|
||||||
|
var ETHAN = &SoundCollection{
|
||||||
Prefix: "ethan",
|
Prefix: "ethan",
|
||||||
Commands: []string{
|
Commands: []string{
|
||||||
"!ethan",
|
"!ethan",
|
||||||
@@ -153,7 +154,8 @@ var ETHAN *SoundCollection = &SoundCollection{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var COW *SoundCollection = &SoundCollection{
|
// COW collection
|
||||||
|
var COW = &SoundCollection{
|
||||||
Prefix: "cow",
|
Prefix: "cow",
|
||||||
Commands: []string{
|
Commands: []string{
|
||||||
"!stan",
|
"!stan",
|
||||||
@@ -166,7 +168,8 @@ var COW *SoundCollection = &SoundCollection{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var BIRTHDAY *SoundCollection = &SoundCollection{
|
// BIRTHDAY collection
|
||||||
|
var BIRTHDAY = &SoundCollection{
|
||||||
Prefix: "birthday",
|
Prefix: "birthday",
|
||||||
Commands: []string{
|
Commands: []string{
|
||||||
"!birthday",
|
"!birthday",
|
||||||
@@ -180,7 +183,8 @@ var BIRTHDAY *SoundCollection = &SoundCollection{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var WOW *SoundCollection = &SoundCollection{
|
// WOW collection
|
||||||
|
var WOW = &SoundCollection{
|
||||||
Prefix: "wow",
|
Prefix: "wow",
|
||||||
Commands: []string{
|
Commands: []string{
|
||||||
"!wowthatscool",
|
"!wowthatscool",
|
||||||
@@ -191,7 +195,8 @@ var WOW *SoundCollection = &SoundCollection{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var COLLECTIONS []*SoundCollection = []*SoundCollection{
|
// COLLECTIONS all collections
|
||||||
|
var COLLECTIONS = []*SoundCollection{
|
||||||
AIRHORN,
|
AIRHORN,
|
||||||
KHALED,
|
KHALED,
|
||||||
CENA,
|
CENA,
|
||||||
@@ -211,6 +216,7 @@ func createSound(Name string, Weight int, PartDelay int) *Sound {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load soundcollection
|
||||||
func (sc *SoundCollection) Load() {
|
func (sc *SoundCollection) Load() {
|
||||||
for _, sound := range sc.Sounds {
|
for _, sound := range sc.Sounds {
|
||||||
sc.soundRange += sound.Weight
|
sc.soundRange += sound.Weight
|
||||||
@@ -218,13 +224,14 @@ func (sc *SoundCollection) Load() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SoundCollection) Random() *Sound {
|
// Random select sound
|
||||||
|
func (sc *SoundCollection) Random() *Sound {
|
||||||
var (
|
var (
|
||||||
i int
|
i int
|
||||||
number int = randomRange(0, s.soundRange)
|
number = randomRange(0, sc.soundRange)
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, sound := range s.Sounds {
|
for _, sound := range sc.Sounds {
|
||||||
i += sound.Weight
|
i += sound.Weight
|
||||||
|
|
||||||
if number < i {
|
if number < i {
|
||||||
@@ -280,7 +287,7 @@ func (s *Sound) Load(c *SoundCollection) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plays this sound over the specified VoiceConnection
|
// Play plays this sound over the specified VoiceConnection
|
||||||
func (s *Sound) Play(vc *discordgo.VoiceConnection) {
|
func (s *Sound) Play(vc *discordgo.VoiceConnection) {
|
||||||
vc.Speaking(true)
|
vc.Speaking(true)
|
||||||
defer vc.Speaking(false)
|
defer vc.Speaking(false)
|
||||||
@@ -360,49 +367,15 @@ func enqueuePlay(user *discordgo.User, guild *discordgo.Guild, coll *SoundCollec
|
|||||||
_, exists := queues[guild.ID]
|
_, exists := queues[guild.ID]
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
if len(queues[guild.ID]) < MAX_QUEUE_SIZE {
|
if len(queues[guild.ID]) < maxQueueSize {
|
||||||
queues[guild.ID] <- play
|
queues[guild.ID] <- play
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
queues[guild.ID] = make(chan *Play, MAX_QUEUE_SIZE)
|
queues[guild.ID] = make(chan *Play, maxQueueSize)
|
||||||
playSound(play, nil)
|
playSound(play, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func trackSoundStats(play *Play) {
|
|
||||||
if rcli == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := rcli.Pipelined(func(pipe *redis.Pipeline) error {
|
|
||||||
var baseChar string
|
|
||||||
|
|
||||||
if play.Forced {
|
|
||||||
baseChar = "f"
|
|
||||||
} else {
|
|
||||||
baseChar = "a"
|
|
||||||
}
|
|
||||||
|
|
||||||
base := fmt.Sprintf("airhorn:%s", baseChar)
|
|
||||||
pipe.Incr("airhorn:total")
|
|
||||||
pipe.Incr(fmt.Sprintf("%s:total", base))
|
|
||||||
pipe.Incr(fmt.Sprintf("%s:sound:%s", base, play.Sound.Name))
|
|
||||||
pipe.Incr(fmt.Sprintf("%s:user:%s:sound:%s", base, play.UserID, play.Sound.Name))
|
|
||||||
pipe.Incr(fmt.Sprintf("%s:guild:%s:sound:%s", base, play.GuildID, play.Sound.Name))
|
|
||||||
pipe.Incr(fmt.Sprintf("%s:guild:%s:chan:%s:sound:%s", base, play.GuildID, play.ChannelID, play.Sound.Name))
|
|
||||||
pipe.SAdd(fmt.Sprintf("%s:users", base), play.UserID)
|
|
||||||
pipe.SAdd(fmt.Sprintf("%s:guilds", base), play.GuildID)
|
|
||||||
pipe.SAdd(fmt.Sprintf("%s:channels", base), play.ChannelID)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"error": err,
|
|
||||||
}).Warning("Failed to track stats in redis")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Play a sound
|
// Play a sound
|
||||||
func playSound(play *Play, vc *discordgo.VoiceConnection) (err error) {
|
func playSound(play *Play, vc *discordgo.VoiceConnection) (err error) {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
@@ -427,9 +400,6 @@ func playSound(play *Play, vc *discordgo.VoiceConnection) (err error) {
|
|||||||
time.Sleep(time.Millisecond * 125)
|
time.Sleep(time.Millisecond * 125)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track stats for this play in redis
|
|
||||||
go trackSoundStats(play)
|
|
||||||
|
|
||||||
// Sleep for a specified amount of time before playing the sound
|
// Sleep for a specified amount of time before playing the sound
|
||||||
time.Sleep(time.Millisecond * 32)
|
time.Sleep(time.Millisecond * 32)
|
||||||
|
|
||||||
@@ -443,7 +413,7 @@ func playSound(play *Play, vc *discordgo.VoiceConnection) (err error) {
|
|||||||
|
|
||||||
// If there is another song in the queue, recurse and play that
|
// If there is another song in the queue, recurse and play that
|
||||||
if len(queues[play.GuildID]) > 0 {
|
if len(queues[play.GuildID]) > 0 {
|
||||||
play := <-queues[play.GuildID]
|
play = <-queues[play.GuildID]
|
||||||
playSound(play, vc)
|
playSound(play, vc)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -456,22 +426,7 @@ func playSound(play *Play, vc *discordgo.VoiceConnection) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func onReady(s *discordgo.Session, event *discordgo.Ready) {
|
func onReady(s *discordgo.Session, event *discordgo.Ready) {
|
||||||
log.Info("Recieved READY payload")
|
log.Info("Received READY payload.")
|
||||||
}
|
|
||||||
|
|
||||||
func onGuildCreate(s *discordgo.Session, event *discordgo.GuildCreate) {
|
|
||||||
/*
|
|
||||||
if event.Guild.Unavailable != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, channel := range event.Guild.Channels {
|
|
||||||
if channel.ID == event.Guild.ID {
|
|
||||||
s.ChannelMessageSend(channel.ID, "**AIRHORN BOT READY FOR HORNING. TYPE `!AIRHORN` WHILE IN A VOICE CHANNEL TO ACTIVATE**")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func scontains(key string, options ...string) bool {
|
func scontains(key string, options ...string) bool {
|
||||||
@@ -483,14 +438,6 @@ func scontains(key string, options ...string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateAirhornsPerSecond(cid string) {
|
|
||||||
current, _ := strconv.Atoi(rcli.Get("airhorn:a:total").Val())
|
|
||||||
time.Sleep(time.Second * 10)
|
|
||||||
latest, _ := strconv.Atoi(rcli.Get("airhorn:a:total").Val())
|
|
||||||
|
|
||||||
discord.ChannelMessageSend(cid, fmt.Sprintf("Current APS: %v", (float64(latest-current))/10.0))
|
|
||||||
}
|
|
||||||
|
|
||||||
func displayBotStats(cid string) {
|
func displayBotStats(cid string) {
|
||||||
stats := runtime.MemStats{}
|
stats := runtime.MemStats{}
|
||||||
runtime.ReadMemStats(&stats)
|
runtime.ReadMemStats(&stats)
|
||||||
@@ -516,45 +463,6 @@ func displayBotStats(cid string) {
|
|||||||
discord.ChannelMessageSend(cid, buf.String())
|
discord.ChannelMessageSend(cid, buf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func utilSumRedisKeys(keys []string) int {
|
|
||||||
results := make([]*redis.StringCmd, 0)
|
|
||||||
|
|
||||||
rcli.Pipelined(func(pipe *redis.Pipeline) error {
|
|
||||||
for _, key := range keys {
|
|
||||||
results = append(results, pipe.Get(key))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
var total int
|
|
||||||
for _, i := range results {
|
|
||||||
t, _ := strconv.Atoi(i.Val())
|
|
||||||
total += t
|
|
||||||
}
|
|
||||||
|
|
||||||
return total
|
|
||||||
}
|
|
||||||
|
|
||||||
func displayUserStats(cid, uid string) {
|
|
||||||
keys, err := rcli.Keys(fmt.Sprintf("airhorn:*:user:%s:sound:*", uid)).Result()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
totalAirhorns := utilSumRedisKeys(keys)
|
|
||||||
discord.ChannelMessageSend(cid, fmt.Sprintf("Total Airhorns: %v", totalAirhorns))
|
|
||||||
}
|
|
||||||
|
|
||||||
func displayServerStats(cid, sid string) {
|
|
||||||
keys, err := rcli.Keys(fmt.Sprintf("airhorn:*:guild:%s:sound:*", sid)).Result()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
totalAirhorns := utilSumRedisKeys(keys)
|
|
||||||
discord.ChannelMessageSend(cid, fmt.Sprintf("Total Airhorns: %v", totalAirhorns))
|
|
||||||
}
|
|
||||||
|
|
||||||
func utilGetMentioned(s *discordgo.Session, m *discordgo.MessageCreate) *discordgo.User {
|
func utilGetMentioned(s *discordgo.Session, m *discordgo.MessageCreate) *discordgo.User {
|
||||||
for _, mention := range m.Mentions {
|
for _, mention := range m.Mentions {
|
||||||
if mention.ID != s.State.Ready.User.ID {
|
if mention.ID != s.State.Ready.User.ID {
|
||||||
@@ -590,19 +498,8 @@ func airhornBomb(cid string, guild *discordgo.Guild, user *discordgo.User, cs st
|
|||||||
func handleBotControlMessages(s *discordgo.Session, m *discordgo.MessageCreate, parts []string, g *discordgo.Guild) {
|
func handleBotControlMessages(s *discordgo.Session, m *discordgo.MessageCreate, parts []string, g *discordgo.Guild) {
|
||||||
if scontains(parts[1], "status") {
|
if scontains(parts[1], "status") {
|
||||||
displayBotStats(m.ChannelID)
|
displayBotStats(m.ChannelID)
|
||||||
} else if scontains(parts[1], "stats") {
|
|
||||||
if len(m.Mentions) >= 2 {
|
|
||||||
displayUserStats(m.ChannelID, utilGetMentioned(s, m).ID)
|
|
||||||
} else if len(parts) >= 3 {
|
|
||||||
displayUserStats(m.ChannelID, parts[2])
|
|
||||||
} else {
|
|
||||||
displayServerStats(m.ChannelID, g.ID)
|
|
||||||
}
|
|
||||||
} else if scontains(parts[1], "bomb") && len(parts) >= 4 {
|
} else if scontains(parts[1], "bomb") && len(parts) >= 4 {
|
||||||
airhornBomb(m.ChannelID, g, utilGetMentioned(s, m), parts[3])
|
airhornBomb(m.ChannelID, g, utilGetMentioned(s, m), parts[3])
|
||||||
} else if scontains(parts[1], "aps") {
|
|
||||||
s.ChannelMessageSend(m.ChannelID, ":ok_hand: give me a sec m8")
|
|
||||||
go calculateAirhornsPerSecond(m.ChannelID)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -610,12 +507,12 @@ func onMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|||||||
if m.Content == "ping" || m.Content == "pong" {
|
if m.Content == "ping" || m.Content == "pong" {
|
||||||
// If the message is "ping" reply with "Pong!"
|
// If the message is "ping" reply with "Pong!"
|
||||||
if m.Content == "ping" {
|
if m.Content == "ping" {
|
||||||
_, _ = s.ChannelMessageSend(m.ChannelID, "Pong!")
|
s.ChannelMessageSend(m.ChannelID, "Pong!")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the message is "pong" reply with "Ping!"
|
// If the message is "pong" reply with "Ping!"
|
||||||
if m.Content == "pong" {
|
if m.Content == "pong" {
|
||||||
_, _ = s.ChannelMessageSend(m.ChannelID, "Ping!")
|
s.ChannelMessageSend(m.ChannelID, "Ping!")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updating bot status
|
// Updating bot status
|
||||||
@@ -690,7 +587,6 @@ func onMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|||||||
func main() {
|
func main() {
|
||||||
var (
|
var (
|
||||||
Token = flag.String("t", "", "Discord Authentication Token")
|
Token = flag.String("t", "", "Discord Authentication Token")
|
||||||
Redis = flag.String("r", "", "Redis Connection String")
|
|
||||||
Shard = flag.String("s", "", "Shard ID")
|
Shard = flag.String("s", "", "Shard ID")
|
||||||
ShardCount = flag.String("c", "", "Number of shards")
|
ShardCount = flag.String("c", "", "Number of shards")
|
||||||
Owner = flag.String("o", "", "Owner ID")
|
Owner = flag.String("o", "", "Owner ID")
|
||||||
@@ -708,23 +604,9 @@ func main() {
|
|||||||
coll.Load()
|
coll.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got passed a redis server, try to connect
|
|
||||||
if *Redis != "" {
|
|
||||||
log.Info("Connecting to redis...")
|
|
||||||
rcli = redis.NewClient(&redis.Options{Addr: *Redis, DB: 0})
|
|
||||||
_, err = rcli.Ping().Result()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"error": err,
|
|
||||||
}).Fatal("Failed to connect to redis")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a discord session
|
// Create a discord session
|
||||||
log.Info("Starting discord session...")
|
log.Info("Starting discord session...")
|
||||||
discord, err = discordgo.New(*Token)
|
discord, err = discordgo.New("Bot " + *Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"error": err,
|
"error": err,
|
||||||
@@ -752,7 +634,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We're running!
|
// We're running!
|
||||||
log.Info("AIRHORNBOT is ready to horn it up.")
|
log.Info("Gidbig is ready. Quit with CTRL-C.")
|
||||||
|
|
||||||
// Wait for a signal to quit
|
// Wait for a signal to quit
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user