2018-08-22 22:44:20 +00:00
|
|
|
package gavalink
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"github.com/gorilla/websocket"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Player is a Lavalink player
|
|
|
|
type Player struct {
|
2018-08-22 22:58:01 +00:00
|
|
|
guildID string
|
|
|
|
time int
|
|
|
|
position int
|
2018-08-23 22:40:36 +00:00
|
|
|
paused bool
|
2018-08-22 22:58:01 +00:00
|
|
|
manager *Lavalink
|
|
|
|
node *Node
|
2018-08-22 23:39:36 +00:00
|
|
|
handler EventHandler
|
2018-08-22 22:44:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Play will play the given track completely
|
|
|
|
func (player *Player) Play(track string) error {
|
|
|
|
return player.PlayAt(track, 0, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
// PlayAt will play the given track at the specified start and end times
|
|
|
|
//
|
|
|
|
// Setting a time to 0 will omit it.
|
|
|
|
func (player *Player) PlayAt(track string, startTime int, endTime int) error {
|
|
|
|
start := strconv.Itoa(startTime)
|
|
|
|
end := strconv.Itoa(endTime)
|
|
|
|
|
|
|
|
msg := message{
|
|
|
|
Op: opPlay,
|
2018-08-23 01:07:22 +00:00
|
|
|
GuildID: player.guildID,
|
2018-08-22 22:44:20 +00:00
|
|
|
Track: track,
|
|
|
|
StartTime: start,
|
|
|
|
EndTime: end,
|
|
|
|
}
|
|
|
|
data, err := json.Marshal(msg)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = player.node.wsConn.WriteMessage(websocket.TextMessage, data)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop will stop the currently playing track
|
|
|
|
func (player *Player) Stop() error {
|
|
|
|
msg := message{
|
|
|
|
Op: opStop,
|
|
|
|
GuildID: player.guildID,
|
|
|
|
}
|
|
|
|
data, err := json.Marshal(msg)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = player.node.wsConn.WriteMessage(websocket.TextMessage, data)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pause will pause or resume the player, depending on the pause parameter
|
|
|
|
func (player *Player) Pause(pause bool) error {
|
2018-08-23 22:40:36 +00:00
|
|
|
player.paused = pause
|
2018-08-22 22:44:20 +00:00
|
|
|
msg := message{
|
|
|
|
Op: opPause,
|
|
|
|
GuildID: player.guildID,
|
|
|
|
Pause: pause,
|
|
|
|
}
|
|
|
|
data, err := json.Marshal(msg)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = player.node.wsConn.WriteMessage(websocket.TextMessage, data)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-08-23 22:40:36 +00:00
|
|
|
// Paused returns whether or not the player is currently paused
|
|
|
|
func (player *Player) Paused() bool {
|
|
|
|
return player.paused
|
|
|
|
}
|
|
|
|
|
2018-08-22 22:44:20 +00:00
|
|
|
// Seek will seek the player to the speicifed position, in millis
|
|
|
|
func (player *Player) Seek(position int) error {
|
|
|
|
msg := message{
|
|
|
|
Op: opSeek,
|
|
|
|
GuildID: player.guildID,
|
|
|
|
Position: position,
|
|
|
|
}
|
|
|
|
data, err := json.Marshal(msg)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = player.node.wsConn.WriteMessage(websocket.TextMessage, data)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-08-23 22:40:36 +00:00
|
|
|
// Position returns the player's position, as reported by Lavalink
|
|
|
|
func (player *Player) Position() int {
|
|
|
|
return player.position
|
|
|
|
}
|
|
|
|
|
2018-08-22 22:44:20 +00:00
|
|
|
// Volume will set the player's volume to the specified value
|
|
|
|
//
|
|
|
|
// volume must be within [0, 1000]
|
|
|
|
func (player *Player) Volume(volume int) error {
|
|
|
|
if volume < 0 || volume > 1000 {
|
|
|
|
return errVolumeOutOfRange
|
|
|
|
}
|
|
|
|
|
|
|
|
msg := message{
|
|
|
|
Op: opVolume,
|
|
|
|
GuildID: player.guildID,
|
|
|
|
Volume: volume,
|
|
|
|
}
|
|
|
|
data, err := json.Marshal(msg)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = player.node.wsConn.WriteMessage(websocket.TextMessage, data)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-08-23 22:44:50 +00:00
|
|
|
// Forward will forward a new VOICE_SERVER_UPDATE to a Lavalink node for
|
|
|
|
// this player.
|
|
|
|
//
|
|
|
|
// This should always be used if a VOICE_SERVER_UPDATE is received for
|
|
|
|
// a guild which already has a player.
|
|
|
|
//
|
|
|
|
// To move a player to a new Node, first player.Destroy() it, and then
|
|
|
|
// create a new player on the new node.
|
|
|
|
func (player *Player) Forward(sessionID string, event VoiceServerUpdate) error {
|
|
|
|
msg := message{
|
|
|
|
Op: opVoiceUpdate,
|
|
|
|
GuildID: player.guildID,
|
|
|
|
SessionID: sessionID,
|
|
|
|
Event: event,
|
|
|
|
}
|
|
|
|
data, err := json.Marshal(msg)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = player.node.wsConn.WriteMessage(websocket.TextMessage, data)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-08-22 22:44:20 +00:00
|
|
|
// Destroy will destroy this player
|
|
|
|
func (player *Player) Destroy() error {
|
|
|
|
msg := message{
|
|
|
|
Op: opDestroy,
|
|
|
|
GuildID: player.guildID,
|
|
|
|
}
|
|
|
|
data, err := json.Marshal(msg)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = player.node.wsConn.WriteMessage(websocket.TextMessage, data)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
player.manager.players[player.guildID] = nil
|
|
|
|
return nil
|
|
|
|
}
|