package main
import (
"bytes"
"encoding/binary"
"flag"
"fmt"
"io"
"math/rand"
"os"
"os/signal"
"runtime"
"strconv"
"strings"
"text/tabwriter"
"time"
log "github.com/Sirupsen/logrus"
"github.com/bwmarrin/discordgo"
humanize "github.com/dustin/go-humanize"
)
var (
// discordgo session
discord *discordgo.Session
// Map of Guild id's to *Play channels, used for queuing and rate-limiting guilds
queues = make(map[string]chan *Play)
// bitrate Sound encoding settings
bitrate = 128
// maxQueueSize Sound encoding settings
maxQueueSize = 6
// OWNER variable
OWNER string
)
// Play represents an individual use of the !airhorn command
type Play struct {
GuildID string
ChannelID string
UserID string
Sound *Sound
// The next play to occur after this, only used for chaining sounds like anotha
Next *Play
// If true, this was a forced play using a specific airhorn sound name
Forced bool
}
// SoundCollection of Sounds
type SoundCollection struct {
Prefix string
Commands []string
Sounds []*Sound
ChainWith *SoundCollection
soundRange int
}
// Sound represents a sound clip
type Sound struct {
Name string
// Weight adjust how likely it is this song will play, higher = more likely
Weight int
// Delay (in milliseconds) for the bot to wait before sending the disconnect request
PartDelay int
// Buffer to store encoded PCM packets
buffer [][]byte
}
// AIRHORN Array of all the sounds we have
var AIRHORN = &SoundCollection{
Prefix: "airhorn",
Commands: []string{
"!airhorn",
},
Sounds: []*Sound{
createSound("default", 1000, 250),
createSound("reverb", 800, 250),
createSound("spam", 800, 0),
createSound("tripletap", 800, 250),
createSound("fourtap", 800, 250),
createSound("distant", 500, 250),
createSound("echo", 500, 250),
createSound("clownfull", 250, 250),
createSound("clownshort", 250, 250),
createSound("clownspam", 250, 0),
createSound("highfartlong", 200, 250),
createSound("highfartshort", 200, 250),
createSound("midshort", 100, 250),
createSound("truck", 10, 250),
},
}
// BSTH collection
var BSTH = &SoundCollection{
Prefix: "bsth",
Commands: []string{
"!bsth",
},
Sounds: []*Sound{
createSound("achso", 1, 250),
createSound("angeben", 1, 250),
createSound("aufwiedersehen", 1, 250),
createSound("bluemchen", 1, 250),
createSound("blutsprobe", 1, 250),
createSound("chefkoch", 1, 250),
createSound("danke", 1, 250),
createSound("eindummer", 1, 250),
createSound("eleganz", 1, 250),
createSound("fettesau", 1, 250),
createSound("fett", 1, 250),
createSound("fressen", 1, 250),
createSound("geraeusch", 1, 250),
createSound("gottseimitdir", 1, 250),
createSound("gruss", 1, 250),
createSound("gulli", 1, 250),
createSound("harfenkonzert", 1, 250),
createSound("hosen", 1, 250),
createSound("indiehose", 1, 250),
createSound("kai", 1, 250),
createSound("kalkleiste", 1, 250),
createSound("keinegrauenzellen", 1, 250),
createSound("kohlen", 1, 250),
createSound("meinspruch", 1, 250),
createSound("miete", 1, 250),
createSound("nuesse", 1, 250),
createSound("ohneheu", 1, 250),
createSound("riecher", 1, 250),
createSound("sauer", 1, 250),
createSound("schatten", 1, 250),
createSound("scheitel", 1, 250),
createSound("solingen", 1, 250),
createSound("unglaublich", 1, 250),
createSound("unmoeglich", 1, 250),
createSound("vortreten", 1, 250),
createSound("zufaellig", 1, 250),
createSound("arschloch", 1, 250),
createSound("aufstossen", 1, 250),
createSound("ausholen", 1, 250),
createSound("blaehungen", 1, 250),
createSound("haesslich", 1, 250),
createSound("horchlappen", 1, 250),
createSound("interesseng", 1, 250),
createSound("keingrips", 1, 250),
createSound("kriegicheineis", 1, 250),
createSound("lachespaeter", 1, 250),
createSound("machtjanix", 1, 250),
createSound("nichtsofett", 1, 250),
createSound("schweine", 1, 250),
createSound("unfreundlich", 1, 250),
createSound("verheiratet", 1, 250),
createSound("zulaut", 1, 250),
},
}
// BSTH2 collection
var BSTH2 = &SoundCollection{
Prefix: "bsth2",
Commands: []string{
"!bsth2",
},
Sounds: []*Sound{
createSound("abendplanung", 1, 250),
createSound("alleine", 1, 250),
createSound("chefkoch", 1, 250),
createSound("fett", 1, 250),
createSound("hubschrauber", 1, 250),
createSound("perspektive", 1, 250),
createSound("platonisch", 1, 250),
createSound("qualle", 1, 250),
},
}
// KHALED collection
var KHALED = &SoundCollection{
Prefix: "another",
ChainWith: AIRHORN,
Commands: []string{
"!anotha",
"!anothaone",
},
Sounds: []*Sound{
createSound("one", 1, 250),
createSound("one_classic", 1, 250),
createSound("one_echo", 1, 250),
},
}
// CENA collection
var CENA = &SoundCollection{
Prefix: "jc",
Commands: []string{
"!johncena",
"!cena",
},
Sounds: []*Sound{
createSound("airhorn", 1, 250),
createSound("echo", 1, 250),
createSound("full", 1, 250),
createSound("jc", 1, 250),
createSound("nameis", 1, 250),
createSound("spam", 1, 250),
},
}
// ETHAN collection
var ETHAN = &SoundCollection{
Prefix: "ethan",
Commands: []string{
"!ethan",
"!eb",
"!ethanbradberry",
"!h3h3",
},
Sounds: []*Sound{
createSound("areyou_classic", 100, 250),
createSound("areyou_condensed", 100, 250),
createSound("areyou_crazy", 100, 250),
createSound("areyou_ethan", 100, 250),
createSound("classic", 100, 250),
createSound("echo", 100, 250),
createSound("high", 100, 250),
createSound("slowandlow", 100, 250),
createSound("cuts", 30, 250),
createSound("beat", 30, 250),
createSound("sodiepop", 1, 250),
},
}
// COW collection
var COW = &SoundCollection{
Prefix: "cow",
Commands: []string{
"!stan",
"!stanislav",
},
Sounds: []*Sound{
createSound("herd", 10, 250),
createSound("moo", 10, 250),
createSound("x3", 1, 250),
},
}
// BIRTHDAY collection
var BIRTHDAY = &SoundCollection{
Prefix: "birthday",
Commands: []string{
"!birthday",
"!bday",
},
Sounds: []*Sound{
createSound("horn", 50, 250),
createSound("horn3", 30, 250),
createSound("sadhorn", 25, 250),
createSound("weakhorn", 25, 250),
},
}
// WOW collection
var WOW = &SoundCollection{
Prefix: "wow",
Commands: []string{
"!wowthatscool",
"!wtc",
},
Sounds: []*Sound{
createSound("thatscool", 50, 250),
},
}
// COLLECTIONS all collections
var COLLECTIONS = []*SoundCollection{
AIRHORN,
KHALED,
CENA,
ETHAN,
COW,
BIRTHDAY,
WOW,
BSTH,
BSTH2,
}
// Create a Sound struct
func createSound(Name string, Weight int, PartDelay int) *Sound {
return &Sound{
Name: Name,
Weight: Weight,
PartDelay: PartDelay,
buffer: make([][]byte, 0),
}
}
// Load soundcollection
func (sc *SoundCollection) Load() {
for _, sound := range sc.Sounds {
sc.soundRange += sound.Weight
sound.Load(sc)
}
}
// Random select sound
func (sc *SoundCollection) Random() *Sound {
var (
i int
number = randomRange(0, sc.soundRange)
)
for _, sound := range sc.Sounds {
i += sound.Weight
if number < i {
return sound
}
}
return nil
}
// Load attempts to load an encoded sound file from disk
// DCA files are pre-computed sound files that are easy to send to Discord.
// If you would like to create your own DCA files, please use:
// https://github.com/nstafie/dca-rs
// eg: dca-rs --raw -i >