arikawa/voice/commands.go

125 lines
3.5 KiB
Go

package voice
import (
"time"
"github.com/diamondburned/arikawa/discord"
)
// OPCode 0
// https://discordapp.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-identify-payload
type IdentifyData struct {
GuildID discord.Snowflake `json:"server_id"` // yes, this should be "server_id"
UserID discord.Snowflake `json:"user_id"`
SessionID string `json:"session_id"`
Token string `json:"token"`
}
// Identify sends an Identify operation (opcode 0) to the Voice Gateway.
func (c *Connection) Identify() error {
guildID := c.GuildID
userID := c.UserID
sessionID := c.SessionID
token := c.Token
if guildID == 0 || userID == 0 || sessionID == "" || token == "" {
return ErrMissingForIdentify
}
return c.Send(IdentifyOP, IdentifyData{
GuildID: guildID,
UserID: userID,
SessionID: sessionID,
Token: token,
})
}
// OPCode 1
// https://discordapp.com/developers/docs/topics/voice-connections#establishing-a-voice-udp-connection-example-select-protocol-payload
type SelectProtocol struct {
Protocol string `json:"protocol"`
Data SelectProtocolData `json:"data"`
}
type SelectProtocolData struct {
Address string `json:"address"`
Port uint16 `json:"port"`
Mode string `json:"mode"`
}
// SelectProtocol sends a Select Protocol operation (opcode 1) to the Voice Gateway.
func (c *Connection) SelectProtocol(data SelectProtocol) error {
return c.Send(SelectProtocolOP, data)
}
// OPCode 3
// https://discordapp.com/developers/docs/topics/voice-connections#heartbeating-example-heartbeat-payload
type Heartbeat uint64
// Heartbeat sends a Heartbeat operation (opcode 3) to the Voice Gateway.
func (c *Connection) Heartbeat() error {
return c.Send(HeartbeatOP, time.Now().UnixNano())
}
// https://discordapp.com/developers/docs/topics/voice-connections#speaking
type Speaking uint64
const (
Microphone Speaking = 1 << iota
Soundshare
Priority
)
// OPCode 5
// https://discordapp.com/developers/docs/topics/voice-connections#speaking-example-speaking-payload
type SpeakingData struct {
Speaking Speaking `json:"speaking"`
Delay int `json:"delay"`
SSRC uint32 `json:"ssrc"`
}
// Speaking sends a Speaking operation (opcode 5) to the Voice Gateway.
func (c *Connection) Speaking(s Speaking) error {
// How do we allow a user to stop speaking?
// Also: https://discordapp.com/developers/docs/topics/voice-connections#voice-data-interpolation
return c.Send(SpeakingOP, SpeakingData{
Speaking: s,
Delay: 0,
SSRC: c.ready.SSRC,
})
}
// StopSpeaking stops speaking.
// https://discordapp.com/developers/docs/topics/voice-connections#voice-data-interpolation
func (c *Connection) StopSpeaking() {
for i := 0; i < 5; i++ {
c.OpusSend <- []byte{0xF8, 0xFF, 0xFE}
}
}
// OPCode 7
// https://discordapp.com/developers/docs/topics/voice-connections#resuming-voice-connection-example-resume-connection-payload
type ResumeData struct {
GuildID discord.Snowflake `json:"server_id"` // yes, this should be "server_id"
SessionID string `json:"session_id"`
Token string `json:"token"`
}
// Resume sends a Resume operation (opcode 7) to the Voice Gateway.
func (c *Connection) Resume() error {
guildID := c.GuildID
sessionID := c.SessionID
token := c.Token
if guildID == 0 || sessionID == "" || token == "" {
return ErrMissingForResume
}
return c.Send(ResumeOP, ResumeData{
GuildID: guildID,
SessionID: sessionID,
Token: token,
})
}