package gavalink import ( "errors" "log" "net/http" "os" "time" ) // Log sets the log.Logger gavalink will write to var Log *log.Logger func init() { Log = log.New(os.Stdout, "(gavalink) ", 0) } // Lavalink manages a connection to Lavalink Nodes type Lavalink struct { shards string userID string nodes []*Node players map[string]*Player capabilities map[string]interface{} BestNodeFunc func([]*Node) (*Node, error) } var ( errNoNodes = errors.New("No nodes present") errNodeNotFound = errors.New("Couldn't find that node") errPlayerNotFound = errors.New("Couldn't find a player for that guild") errVolumeOutOfRange = errors.New("Volume is out of range, must be within [0, 1000]") errInvalidVersion = errors.New("This library requires Lavalink >= 3") errUnknownPayload = errors.New("Lavalink sent an unknown payload") errNilHandler = errors.New("You must provide an event handler. Use gavalink.DummyEventHandler if you wish to ignore events") ) // NewLavalink creates a new Lavalink manager func NewLavalink(shards string, userID string) *Lavalink { return &Lavalink{ shards: shards, userID: userID, players: make(map[string]*Player), BestNodeFunc: BestNodeByPenalties, } } // AddNodes adds a node to the Lavalink manager func (lavalink *Lavalink) AddNodes(nodeConfigs ...NodeConfig) error { nodes := make([]*Node, len(nodeConfigs)) client := &http.Client{ Timeout: 60 * time.Second, } for i, c := range nodeConfigs { n := &Node{ config: c, manager: lavalink, client: client, } err := n.open() if err != nil { return err } nodes[i] = n } lavalink.nodes = append(lavalink.nodes, nodes...) return nil } // RemoveNode removes a node from the manager func (lavalink *Lavalink) removeNode(node *Node) error { idx := -1 for i, n := range lavalink.nodes { if n == node { idx = i break } } if idx == -1 { return errNodeNotFound } node.stop() for _, player := range lavalink.players { if player.node == node { n, err := lavalink.BestNode() if err != nil { continue } player.ChangeNode(n) } } // temp var for easier reading n := lavalink.nodes z := len(n) - 1 n[idx] = n[z] // swap idx with last n = n[:z] lavalink.nodes = n return nil } // BestNode returns the Node with the lowest latency func (lavalink *Lavalink) BestNode() (*Node, error) { if len(lavalink.nodes) < 1 { return nil, errNoNodes } return lavalink.BestNodeFunc(lavalink.nodes) } // GetPlayer gets a player for a guild func (lavalink *Lavalink) GetPlayer(guild string) (*Player, error) { p, ok := lavalink.players[guild] if !ok { return nil, errPlayerNotFound } return p, nil } // Add capabilities mappings to the client, letting the server know what we support func (lavalink *Lavalink) AddCapability(key string, i interface{}) { if lavalink.capabilities == nil { lavalink.capabilities = make(map[string]interface{}) } lavalink.capabilities[key] = i }