2019-05-10 08:53:58 +00:00
|
|
|
package discord
|
|
|
|
|
|
|
|
import (
|
2019-07-28 20:10:24 +00:00
|
|
|
"encoding/binary"
|
2019-05-10 08:53:58 +00:00
|
|
|
"fmt"
|
2019-07-28 20:10:24 +00:00
|
|
|
"io"
|
2019-05-10 09:55:52 +00:00
|
|
|
"log"
|
2019-07-28 20:10:24 +00:00
|
|
|
"os"
|
2019-05-10 08:53:58 +00:00
|
|
|
|
|
|
|
"galched-bot/modules/settings"
|
2019-05-10 12:16:35 +00:00
|
|
|
"galched-bot/modules/subday"
|
2019-05-10 08:53:58 +00:00
|
|
|
|
2019-07-28 20:10:24 +00:00
|
|
|
"go.uber.org/atomic"
|
|
|
|
|
2019-05-10 08:53:58 +00:00
|
|
|
"github.com/bwmarrin/discordgo"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
Discord struct {
|
2019-05-10 09:55:52 +00:00
|
|
|
appVersion string
|
|
|
|
processor *HandlerProcessor
|
|
|
|
session *discordgo.Session
|
2019-05-10 08:53:58 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2019-05-10 12:16:35 +00:00
|
|
|
func New(s *settings.Settings, subday *subday.Subday) (*Discord, error) {
|
2019-05-10 08:53:58 +00:00
|
|
|
key := fmt.Sprintf("Bot %s", s.DiscordToken)
|
|
|
|
instance, err := discordgo.New(key)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "cannot create discord instance")
|
|
|
|
}
|
2019-05-10 09:55:52 +00:00
|
|
|
|
|
|
|
processor := NewProcessor(s.Version)
|
2019-05-10 12:16:35 +00:00
|
|
|
for _, subdayHandler := range SubdayHandlers(subday, s.PermittedRoles) {
|
|
|
|
processor.AddHandler(subdayHandler)
|
|
|
|
}
|
2019-05-10 09:55:52 +00:00
|
|
|
|
2019-07-28 20:10:24 +00:00
|
|
|
polka, err := loadSong(s.PolkaPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "cannot read polka song")
|
|
|
|
}
|
|
|
|
processor.AddHandler(&polkaHandler{
|
|
|
|
polka: polka,
|
|
|
|
voiceChannel: s.DiscordVoiceChannel,
|
|
|
|
lock: atomic.NewBool(false),
|
|
|
|
})
|
|
|
|
|
2019-05-10 09:55:52 +00:00
|
|
|
log.Printf("discord: added %d message handlers", len(processor.handlers))
|
|
|
|
if len(processor.handlers) > 0 {
|
|
|
|
for i := range processor.handlers {
|
|
|
|
log.Printf("discord: %d) %s", i+1, processor.handlers[i].Signature())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return &Discord{
|
|
|
|
appVersion: s.Version,
|
|
|
|
processor: processor,
|
|
|
|
session: instance,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-07-28 20:10:24 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 09:55:52 +00:00
|
|
|
func LogMessage(m *discordgo.MessageCreate) {
|
|
|
|
log.Printf("discord: msg [%s]: %s", m.Author.Username, m.Content)
|
2019-05-10 08:53:58 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 12:16:35 +00:00
|
|
|
func SendMessage(s *discordgo.Session, m *discordgo.MessageCreate, text string) {
|
|
|
|
_, err := s.ChannelMessageSend(m.ChannelID, text)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("discord: cannot send message [%s]: %v", text, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 08:53:58 +00:00
|
|
|
func (d *Discord) Start() error {
|
2019-05-10 09:55:52 +00:00
|
|
|
d.session.AddHandler(d.processor.Process)
|
2019-05-10 08:53:58 +00:00
|
|
|
return d.session.Open()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Discord) Stop() error {
|
|
|
|
return d.session.Close()
|
|
|
|
}
|