Add universal music handler and update discordgo version
This commit is contained in:
parent
8b5673434a
commit
65fc1ccad4
7 changed files with 246 additions and 155 deletions
|
@ -1,5 +1,12 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 4.2.0 - 2019-10-20
|
||||||
|
### Added
|
||||||
|
- Universal song handler with polka and sax commands
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Updated discordgo library up to v0.20.1
|
||||||
|
|
||||||
## 4.1.0 - 2019-07-28
|
## 4.1.0 - 2019-07-28
|
||||||
### Added
|
### Added
|
||||||
- Song player handler
|
- Song player handler
|
||||||
|
|
7
go.mod
7
go.mod
|
@ -1,8 +1,9 @@
|
||||||
module galched-bot
|
module galched-bot
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bwmarrin/discordgo v0.19.0
|
github.com/bwmarrin/discordgo v0.20.1
|
||||||
github.com/gempir/go-twitch-irc/v2 v2.2.0
|
github.com/gempir/go-twitch-irc/v2 v2.2.0
|
||||||
|
github.com/gorilla/websocket v1.4.1 // indirect
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
github.com/stretchr/testify v1.3.0 // indirect
|
github.com/stretchr/testify v1.3.0 // indirect
|
||||||
go.uber.org/atomic v1.3.2
|
go.uber.org/atomic v1.3.2
|
||||||
|
@ -10,4 +11,8 @@ require (
|
||||||
go.uber.org/fx v1.9.0
|
go.uber.org/fx v1.9.0
|
||||||
go.uber.org/goleak v0.10.0 // indirect
|
go.uber.org/goleak v0.10.0 // indirect
|
||||||
go.uber.org/multierr v1.1.0 // indirect
|
go.uber.org/multierr v1.1.0 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20191018095205-727590c5006e // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
18
go.sum
18
go.sum
|
@ -1,13 +1,13 @@
|
||||||
github.com/bwmarrin/discordgo v0.19.0 h1:kMED/DB0NR1QhRcalb85w0Cu3Ep2OrGAqZH1R5awQiY=
|
github.com/bwmarrin/discordgo v0.20.1 h1:Ihh3/mVoRwy3otmaoPDUioILBJq4fdWkpsi83oj2Lmk=
|
||||||
github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
|
github.com/bwmarrin/discordgo v0.20.1/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/gempir/go-twitch-irc v1.1.0 h1:Q9gQGI/3yJzYwlYDlFsGJzWfpaqubMExfmBXNpOC6W0=
|
|
||||||
github.com/gempir/go-twitch-irc v1.1.0/go.mod h1:Pc661rsUSmkQXvI9W2bNyLt4ZrMAgHZPnVwMQEJ0fdo=
|
|
||||||
github.com/gempir/go-twitch-irc/v2 v2.2.0 h1:9iYRr/PkT5tqnD9J0awBXtwS4R4DatA5cMQbsua6OvM=
|
github.com/gempir/go-twitch-irc/v2 v2.2.0 h1:9iYRr/PkT5tqnD9J0awBXtwS4R4DatA5cMQbsua6OvM=
|
||||||
github.com/gempir/go-twitch-irc/v2 v2.2.0/go.mod h1:0HXoEr9l7gNjwajosptV0w0xGpHeU6gsD7JDlfvjTYI=
|
github.com/gempir/go-twitch-irc/v2 v2.2.0/go.mod h1:0HXoEr9l7gNjwajosptV0w0xGpHeU6gsD7JDlfvjTYI=
|
||||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
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/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||||
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
@ -27,3 +27,13 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA=
|
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=
|
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191018095205-727590c5006e h1:ZtoklVMHQy6BFRHkbG6JzK+S6rX82//Yeok1vMlizfQ=
|
||||||
|
golang.org/x/sys v0.0.0-20191018095205-727590c5006e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
package discord
|
package discord
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
|
|
||||||
"galched-bot/modules/settings"
|
"galched-bot/modules/settings"
|
||||||
"galched-bot/modules/subday"
|
"galched-bot/modules/subday"
|
||||||
|
|
||||||
"go.uber.org/atomic"
|
|
||||||
|
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -36,15 +31,9 @@ func New(s *settings.Settings, subday *subday.Subday) (*Discord, error) {
|
||||||
processor.AddHandler(subdayHandler)
|
processor.AddHandler(subdayHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
polka, err := loadSong(s.PolkaPath)
|
for _, songHandler := range SongHandlers(s) {
|
||||||
if err != nil {
|
processor.AddHandler(songHandler)
|
||||||
return nil, errors.Wrap(err, "cannot read polka song")
|
|
||||||
}
|
}
|
||||||
processor.AddHandler(&polkaHandler{
|
|
||||||
polka: polka,
|
|
||||||
voiceChannel: s.DiscordVoiceChannel,
|
|
||||||
lock: atomic.NewBool(false),
|
|
||||||
})
|
|
||||||
|
|
||||||
log.Printf("discord: added %d message handlers", len(processor.handlers))
|
log.Printf("discord: added %d message handlers", len(processor.handlers))
|
||||||
if len(processor.handlers) > 0 {
|
if len(processor.handlers) > 0 {
|
||||||
|
@ -60,48 +49,6 @@ func New(s *settings.Settings, subday *subday.Subday) (*Discord, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSong(path string) ([][]byte, error) {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error opening dca file")
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
opuslen int16
|
|
||||||
buffer = make([][]byte, 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
for {
|
|
||||||
// Read opus frame length from dca file.
|
|
||||||
err = binary.Read(file, binary.LittleEndian, &opuslen)
|
|
||||||
|
|
||||||
// If this is the end of the file, just return.
|
|
||||||
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
|
||||||
err := file.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return buffer, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error reading from dca file")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read encoded pcm from dca file.
|
|
||||||
InBuf := make([]byte, opuslen)
|
|
||||||
err = binary.Read(file, binary.LittleEndian, &InBuf)
|
|
||||||
|
|
||||||
// Should not be any end of file errors
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error reading from dca file")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append encoded pcm data to the buffer.
|
|
||||||
buffer = append(buffer, InBuf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func LogMessage(m *discordgo.MessageCreate) {
|
func LogMessage(m *discordgo.MessageCreate) {
|
||||||
log.Printf("discord: msg [%s]: %s", m.Author.Username, m.Content)
|
log.Printf("discord: msg [%s]: %s", m.Author.Username, m.Content)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
package discord
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/bwmarrin/discordgo"
|
|
||||||
"go.uber.org/atomic"
|
|
||||||
)
|
|
||||||
|
|
||||||
type polkaHandler struct {
|
|
||||||
polka [][]byte
|
|
||||||
voiceChannel string
|
|
||||||
lock *atomic.Bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *polkaHandler) Signature() string {
|
|
||||||
return "!song"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *polkaHandler) Description() string {
|
|
||||||
return "сыграть гимн галчед (только для избранных)"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *polkaHandler) IsValid(msg string) bool {
|
|
||||||
return msg == "!song"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *polkaHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|
||||||
if m.Author.Username != "YoMedved" && m.Author.Username != "Rummy_Quamox" && m.Author.Username != "Lidiya_owl" {
|
|
||||||
log.Printf("discord: unathorized polka message from %s", m.Author.Username)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the channel that the message came from.
|
|
||||||
c, err := s.State.Channel(m.ChannelID)
|
|
||||||
if err != nil {
|
|
||||||
// Could not find channel.
|
|
||||||
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 guild's current voice states.
|
|
||||||
LogMessage(m)
|
|
||||||
if h.lock.CAS(false, true) {
|
|
||||||
defer h.lock.Store(false)
|
|
||||||
err = h.playSound(s, g.ID, h.voiceChannel)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("discord: error playing sound:", err)
|
|
||||||
}
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// playSound plays the current buffer to the provided channel.
|
|
||||||
func (h *polkaHandler) playSound(s *discordgo.Session, guildID, channelID string) (err error) {
|
|
||||||
|
|
||||||
// Join the provided voice channel.
|
|
||||||
vc, err := s.ChannelVoiceJoin(guildID, channelID, false, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sleep for a specified amount of time before playing the sound
|
|
||||||
time.Sleep(250 * time.Millisecond)
|
|
||||||
|
|
||||||
// Start speaking.
|
|
||||||
vc.Speaking(true)
|
|
||||||
|
|
||||||
// Send the buffer data.
|
|
||||||
for _, buff := range h.polka {
|
|
||||||
vc.OpusSend <- buff
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop speaking
|
|
||||||
vc.Speaking(false)
|
|
||||||
|
|
||||||
// Sleep for a specified amount of time before ending.
|
|
||||||
time.Sleep(250 * time.Millisecond)
|
|
||||||
|
|
||||||
// Disconnect from the provided voice channel.
|
|
||||||
vc.Disconnect()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
191
modules/discord/songhandlers.go
Normal file
191
modules/discord/songhandlers.go
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"go.uber.org/atomic"
|
||||||
|
|
||||||
|
"galched-bot/modules/settings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
songData [][]byte
|
||||||
|
|
||||||
|
SongHandler struct {
|
||||||
|
globalLock *atomic.Bool
|
||||||
|
songLock *atomic.Bool
|
||||||
|
|
||||||
|
song songData
|
||||||
|
signature string
|
||||||
|
description string
|
||||||
|
voiceChannel string
|
||||||
|
permissions []string
|
||||||
|
timeout time.Duration
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *SongHandler) Signature() string {
|
||||||
|
return h.signature
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *SongHandler) Description() string {
|
||||||
|
return h.description
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *SongHandler) IsValid(msg string) bool {
|
||||||
|
return msg == h.signature
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *SongHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||||
|
var permitted bool
|
||||||
|
for i := range h.permissions {
|
||||||
|
if m.Author.Username == h.permissions[i] {
|
||||||
|
permitted = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(h.permissions) > 0 && !permitted {
|
||||||
|
log.Printf("discord: unathorized %s message from %s",
|
||||||
|
h.signature, m.Author.Username)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the channel that the message came from.
|
||||||
|
c, err := s.State.Channel(m.ChannelID)
|
||||||
|
if err != nil {
|
||||||
|
// Could not find channel.
|
||||||
|
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 guild's current voice states.
|
||||||
|
LogMessage(m)
|
||||||
|
if h.globalLock.CAS(false, true) {
|
||||||
|
if h.songLock.CAS(false, true) {
|
||||||
|
|
||||||
|
err = playSound(s, g.ID, h.voiceChannel, h.song)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("discord: error playing sound:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
h.globalLock.Store(false)
|
||||||
|
time.Sleep(h.timeout)
|
||||||
|
defer h.songLock.Store(false)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.globalLock.Store(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SongHandlers(s *settings.Settings) []MessageHandler {
|
||||||
|
result := make([]MessageHandler, 0, len(s.Songs))
|
||||||
|
g := new(atomic.Bool)
|
||||||
|
|
||||||
|
for i := range s.Songs {
|
||||||
|
song, err := loadSong(s.Songs[i].Path)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("discord: error loading song file", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
handler := &SongHandler{
|
||||||
|
globalLock: g,
|
||||||
|
songLock: new(atomic.Bool),
|
||||||
|
song: song,
|
||||||
|
signature: s.Songs[i].Signature,
|
||||||
|
description: s.Songs[i].Description,
|
||||||
|
voiceChannel: s.DiscordVoiceChannel,
|
||||||
|
permissions: s.Songs[i].Permissions,
|
||||||
|
timeout: s.Songs[i].Timeout,
|
||||||
|
}
|
||||||
|
result = append(result, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// playSound plays the current buffer to the provided channel.
|
||||||
|
func playSound(s *discordgo.Session, guildID, channelID string, song songData) error {
|
||||||
|
|
||||||
|
// Join the provided voice channel.
|
||||||
|
vc, err := s.ChannelVoiceJoin(guildID, channelID, false, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sleep for a specified amount of time before playing the sound
|
||||||
|
time.Sleep(250 * time.Millisecond)
|
||||||
|
|
||||||
|
// Start speaking.
|
||||||
|
vc.Speaking(true)
|
||||||
|
|
||||||
|
// Send the buffer data.
|
||||||
|
for _, buff := range song {
|
||||||
|
vc.OpusSend <- buff
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop speaking
|
||||||
|
vc.Speaking(false)
|
||||||
|
|
||||||
|
// Sleep for a specified amount of time before ending.
|
||||||
|
time.Sleep(250 * time.Millisecond)
|
||||||
|
|
||||||
|
// Disconnect from the provided voice channel.
|
||||||
|
vc.Disconnect()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadSong(path string) (songData, error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error opening dca file")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
opuslen int16
|
||||||
|
buffer = make(songData, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
for {
|
||||||
|
// Read opus frame length from dca file.
|
||||||
|
err = binary.Read(file, binary.LittleEndian, &opuslen)
|
||||||
|
|
||||||
|
// If this is the end of the file, just return.
|
||||||
|
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
||||||
|
err := file.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buffer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error reading from dca file")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read encoded pcm from dca file.
|
||||||
|
InBuf := make([]byte, opuslen)
|
||||||
|
err = binary.Read(file, binary.LittleEndian, &InBuf)
|
||||||
|
|
||||||
|
// Should not be any end of file errors
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error reading from dca file")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append encoded pcm data to the buffer.
|
||||||
|
buffer = append(buffer, InBuf)
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,10 +3,11 @@ package settings
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = "4.1.0"
|
version = "4.2.0"
|
||||||
twitchUser = "galchedbot"
|
twitchUser = "galchedbot"
|
||||||
twitchIRCRoom = "galched"
|
twitchIRCRoom = "galched"
|
||||||
discordTokenPath = "./tokens/.discordtoken"
|
discordTokenPath = "./tokens/.discordtoken"
|
||||||
|
@ -21,6 +22,14 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
SongInfo struct {
|
||||||
|
Path string
|
||||||
|
Signature string
|
||||||
|
Description string
|
||||||
|
Permissions []string
|
||||||
|
Timeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
Settings struct {
|
Settings struct {
|
||||||
Version string
|
Version string
|
||||||
DiscordToken string
|
DiscordToken string
|
||||||
|
@ -29,8 +38,8 @@ type (
|
||||||
TwitchToken string
|
TwitchToken string
|
||||||
SubdayDataPath string
|
SubdayDataPath string
|
||||||
PermittedRoles []string
|
PermittedRoles []string
|
||||||
PolkaPath string
|
|
||||||
DiscordVoiceChannel string
|
DiscordVoiceChannel string
|
||||||
|
Songs []SongInfo
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,8 +60,22 @@ func New() (*Settings, error) {
|
||||||
TwitchUser: twitchUser,
|
TwitchUser: twitchUser,
|
||||||
TwitchIRCRoom: twitchIRCRoom,
|
TwitchIRCRoom: twitchIRCRoom,
|
||||||
SubdayDataPath: subdayDataPath,
|
SubdayDataPath: subdayDataPath,
|
||||||
PolkaPath: "songs/polka.dca",
|
|
||||||
DiscordVoiceChannel: "301793085522706432",
|
DiscordVoiceChannel: "301793085522706432",
|
||||||
PermittedRoles: []string{subRole1, subRole2, galchedRole, smorcRole},
|
PermittedRoles: []string{subRole1, subRole2, galchedRole, smorcRole},
|
||||||
|
Songs: []SongInfo{
|
||||||
|
{
|
||||||
|
Path: "songs/polka.dca",
|
||||||
|
Signature: "!song",
|
||||||
|
Description: "сыграть гимн галчед (только для избранных",
|
||||||
|
Permissions: []string{"AlexV", "Rummy_Quamox", "Lidiya_owl"},
|
||||||
|
Timeout: 10 * time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "songs/whisper.dca",
|
||||||
|
Signature: "!sax",
|
||||||
|
Description: "kreygasm",
|
||||||
|
Timeout: 20 * time.Second,
|
||||||
|
},
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue