1
0
mirror of https://github.com/mgerb/go-discord-bot synced 2026-01-10 17:12:48 +00:00

allow sounds to be queued up - summon/dimiss now a thing

This commit is contained in:
2017-06-29 23:52:23 -05:00
parent 55bbf7cc1f
commit 03fa82b2a2
10 changed files with 126 additions and 107 deletions

View File

@@ -1,8 +1,7 @@
// IMPORTANT - rename this file to config.json and remove this line
{ {
"Token": "", "Token": "",
"BotPrefix": "#", "BotPrefix": "#",
"SoundsPath": "./sounds/", "SoundsPath": "./sounds/",
"UploadPassword": "", "UploadPassword": "",
"ServerAddr": ":80" "ServerAddr": ":80"
} }

36
glide.lock generated
View File

@@ -1,36 +0,0 @@
hash: aa2cc77713b57b79c4fc5bd35494fc4077e122137fdd68fa77aab8fdbc4215c8
updated: 2017-06-28T22:24:45.223511-05:00
imports:
- name: github.com/buaazp/fasthttprouter
version: ade4e2031af3aed7fffd241084aad80a58faf421
- name: github.com/bwmarrin/discordgo
version: 0993a94b4e1c3291bed2047f583f34792269355c
- name: github.com/gorilla/websocket
version: ea4d1f681babbce9545c9c5f3d5194a789c89f5b
- name: github.com/karalabe/xgo
version: 34c7afab9a8eb8bff579e20bdbce9a764ce2a9ab
- name: github.com/klauspost/compress
version: f3dce52e0576655d55fd69e74b63da96ad1108f3
subpackages:
- flate
- gzip
- zlib
- name: github.com/klauspost/cpuid
version: 09cded8978dc9e80714c4d85b0322337b0a1e5e0
- name: github.com/tidwall/gjson
version: c784c417818f59d6597274642d8ac1d09efc9b01
- name: github.com/tidwall/match
version: 173748da739a410c5b0b813b956f89ff94730b4c
- name: github.com/valyala/fasthttp
version: d42167fd04f636e20b005e9934159e95454233c7
subpackages:
- fasthttputil
- name: golang.org/x/crypto
version: 84f24dfdf3c414ed893ca1b318d0045ef5a1f607
subpackages:
- nacl/secretbox
- poly1305
- salsa20/salsa
- name: layeh.com/gopus
version: 0ebf989153aa016ef5e77141b08c48e48a79312e
testImports: []

View File

@@ -1,11 +0,0 @@
package: .
import:
- package: github.com/buaazp/fasthttprouter
version: ^0.1.1
- package: github.com/bwmarrin/discordgo
version: ^0.16.0
- package: github.com/tidwall/gjson
- package: github.com/valyala/fasthttp
version: ^20160617.0.0
- package: layeh.com/gopus
- package: github.com/karalabe/xgo

View File

@@ -2,7 +2,7 @@ run:
go run ./server/main.go go run ./server/main.go
install: install:
glide install && yarn install go get ./server && yarn install
build: build:
go build -o ./dist/bot ./server/main.go go build -o ./dist/bot ./server/main.go

View File

@@ -24,7 +24,7 @@ Sounds are stored in the `dist/sounds` directory. You may copy files directly to
### Dependencies ### Dependencies
- Go - Go
- Glide - [GoLang package manager](https://glide.sh/) - Godep - [Godep package manager](https://github.com/tools/godep)
- Yarn (or npm - makefile will need to be adjusted) - Yarn (or npm - makefile will need to be adjusted)
- make - make

View File

@@ -7,14 +7,15 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"log"
"os/exec" "os/exec"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"../config"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"github.com/mgerb/go-discord-bot/server/config"
"layeh.com/gopus" "layeh.com/gopus"
) )
@@ -27,7 +28,9 @@ const (
var ( var (
sounds = make(map[string]*AudioClip, 0) sounds = make(map[string]*AudioClip, 0)
soundQueue = []string{}
soundPlayingLock = false soundPlayingLock = false
voiceConnection *discordgo.VoiceConnection
) )
type AudioClip struct { type AudioClip struct {
@@ -40,27 +43,35 @@ const SOUNDS_DIR string = "./sounds/"
func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) { func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
// exit function call if sound is playing
if soundPlayingLock {
fmt.Println("Function in progress, exiting function call...")
return
}
// check if valid command // check if valid command
if strings.HasPrefix(m.Content, config.Config.BotPrefix) { if strings.HasPrefix(m.Content, config.Config.BotPrefix) {
soundName := strings.TrimPrefix(m.Content, config.Config.BotPrefix) command := strings.TrimPrefix(m.Content, config.Config.BotPrefix)
// check if sound exists in memory switch command {
if _, ok := sounds[soundName]; !ok {
// try to load the sound if not found in memory
err := loadFile(soundName)
if err != nil { case "summon":
fmt.Println(err) summon(s, m)
return
} case "dismiss":
dismiss()
default:
playAudio(command, s, m)
} }
}
}
func dismiss() {
if voiceConnection != nil {
voiceConnection.Disconnect()
}
}
func summon(s *discordgo.Session, m *discordgo.MessageCreate) {
// Join the channel the user issued the command from if not in it
if voiceConnection == nil || voiceConnection.ChannelID != m.ChannelID {
var err error
// Find the channel that the message came from. // Find the channel that the message came from.
c, err := s.State.Channel(m.ChannelID) c, err := s.State.Channel(m.ChannelID)
@@ -73,21 +84,73 @@ func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
// Find the guild for that channel. // Find the guild for that channel.
g, err := s.State.Guild(c.GuildID) g, err := s.State.Guild(c.GuildID)
if err != nil { if err != nil {
// Could not find guild. log.Println(err)
return return
} }
// Look for the message sender in that guilds current voice states. // Look for the message sender in that guilds current voice states.
for _, vs := range g.VoiceStates { for _, vs := range g.VoiceStates {
if vs.UserID == m.Author.ID { if vs.UserID == m.Author.ID {
err = playSound(s, g.ID, vs.ChannelID, soundName)
voiceConnection, err = s.ChannelVoiceJoin(g.ID, vs.ChannelID, false, false)
if err != nil { if err != nil {
fmt.Println("Error playing sound:", err) log.Println(err)
} }
return return
} }
} }
}
}
func playAudio(soundName string, s *discordgo.Session, m *discordgo.MessageCreate) {
// check if sound exists in memory
if _, ok := sounds[soundName]; !ok {
// try to load the sound if not found in memory
err := loadFile(soundName)
if err != nil {
fmt.Println(err)
return
}
}
// add sound to queue
soundQueue = append(soundQueue, soundName)
// return if a sound is playing - it will play if it's in the queue
if soundPlayingLock {
return
}
// Find the channel that the message came from.
c, err := s.State.Channel(m.ChannelID)
if err != nil {
// Could not find channel.
fmt.Println("User channel not found.")
return
}
// Find the guild for that channel.
g, err := s.State.Guild(c.GuildID)
if err != nil {
// Could not find guild.
return
}
// Look for the message sender in that guilds current voice states.
for _, vs := range g.VoiceStates {
if vs.UserID == m.Author.ID {
err = playSounds(s, g.ID, vs.ChannelID)
if err != nil {
fmt.Println("Error playing sound:", err)
}
return
}
} }
} }
@@ -177,45 +240,47 @@ func loadFile(fileName string) error {
sounds[fileName].Content = append(sounds[fileName].Content, opus) sounds[fileName].Content = append(sounds[fileName].Content, opus)
} }
return nil
} }
// playSound plays the current buffer to the provided channel. // playSounds - plays the current buffer to the provided channel.
func playSound(s *discordgo.Session, guildID, channelID string, sound string) (err error) { func playSounds(s *discordgo.Session, guildID, channelID string) (err error) {
if _, ok := sounds[sound]; !ok {
return errors.New("Sound not found")
}
//prevent other sounds from interrupting //prevent other sounds from interrupting
soundPlayingLock = true soundPlayingLock = true
// Join the provided voice channel. // Join the channel the user issued the command from if not in it
vc, err := s.ChannelVoiceJoin(guildID, channelID, false, false) if voiceConnection == nil || voiceConnection.ChannelID != channelID {
if err != nil { var err error
return err voiceConnection, err = s.ChannelVoiceJoin(guildID, channelID, false, false)
if err != nil {
return err
}
} }
// Sleep for a specified amount of time before playing the sound // keep playing sounds as long as they exist in queue
time.Sleep(100 * time.Millisecond) for len(soundQueue) > 0 {
// Start speaking. // Sleep for a specified amount of time before playing the sound
_ = vc.Speaking(true) time.Sleep(50 * time.Millisecond)
// Start speaking.
_ = voiceConnection.Speaking(true)
// Send the buffer data.
for _, buff := range sounds[soundQueue[0]].Content {
voiceConnection.OpusSend <- buff
}
// Stop speaking
_ = voiceConnection.Speaking(false)
// Sleep for a specificed amount of time before ending.
time.Sleep(50 * time.Millisecond)
soundQueue = append(soundQueue[1:])
// Send the buffer data.
for _, buff := range sounds[sound].Content {
vc.OpusSend <- buff
} }
// Stop speaking
_ = vc.Speaking(false)
// Sleep for a specificed amount of time before ending.
time.Sleep(250 * time.Millisecond)
// Disconnect from the provided voice channel.
_ = vc.Disconnect()
soundPlayingLock = false soundPlayingLock = false
return nil return nil

View File

@@ -1,10 +1,10 @@
package main package main
import ( import (
"./bot" "github.com/mgerb/go-discord-bot/server/bot"
"./bothandlers" "github.com/mgerb/go-discord-bot/server/bothandlers"
"./config" "github.com/mgerb/go-discord-bot/server/config"
"./webserver" "github.com/mgerb/go-discord-bot/server/webserver"
) )
func main() { func main() {

View File

@@ -1,12 +1,13 @@
package handlers package handlers
import ( import (
"../../config"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/valyala/fasthttp"
"io/ioutil" "io/ioutil"
"strings" "strings"
"github.com/mgerb/go-discord-bot/server/config"
"github.com/valyala/fasthttp"
) )
var soundList []sound var soundList []sound

View File

@@ -1,10 +1,11 @@
package handlers package handlers
import ( import (
"../../config"
"github.com/valyala/fasthttp"
"io" "io"
"os" "os"
"github.com/mgerb/go-discord-bot/server/config"
"github.com/valyala/fasthttp"
) )
func FileUpload(ctx *fasthttp.RequestCtx) { func FileUpload(ctx *fasthttp.RequestCtx) {

View File

@@ -3,9 +3,9 @@ package webserver
import ( import (
"log" "log"
"../config"
"./handlers"
"github.com/buaazp/fasthttprouter" "github.com/buaazp/fasthttprouter"
"github.com/mgerb/go-discord-bot/server/config"
"github.com/mgerb/go-discord-bot/server/webserver/handlers"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
) )