diff --git a/lavalink.go b/lavalink.go index 0ccae4e..b64bdac 100644 --- a/lavalink.go +++ b/lavalink.go @@ -19,8 +19,10 @@ type Lavalink struct { shards string userID string - nodes []Node + nodes []*Node players map[string]*Player + + BestNodeFunc func([]*Node) (*Node, error) } var ( @@ -36,19 +38,20 @@ var ( // NewLavalink creates a new Lavalink manager func NewLavalink(shards string, userID string) *Lavalink { return &Lavalink{ - shards: shards, - userID: userID, - /* nodes: make([]Node, 1),*/ + shards: shards, + userID: userID, players: make(map[string]*Player), + + BestNodeFunc: BestNodeByLoad, } } // AddNodes adds a node to the Lavalink manager func (lavalink *Lavalink) AddNodes(nodeConfigs ...NodeConfig) error { - nodes := make([]Node, len(nodeConfigs)) + nodes := make([]*Node, len(nodeConfigs)) for i, c := range nodeConfigs { - n := Node{ + n := &Node{ config: c, manager: lavalink, } @@ -71,7 +74,7 @@ func (lavalink *Lavalink) AddNodes(nodeConfigs ...NodeConfig) error { func (lavalink *Lavalink) removeNode(node *Node) error { idx := -1 for i, n := range lavalink.nodes { - if n == *node { + if n == node { idx = i break } @@ -82,6 +85,18 @@ func (lavalink *Lavalink) removeNode(node *Node) error { 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 @@ -99,11 +114,7 @@ func (lavalink *Lavalink) BestNode() (*Node, error) { return nil, errNoNodes } - sort.SliceStable(lavalink.nodes, func(i, j int) bool { - return lavalink.nodes[i].load < lavalink.nodes[j].load - }) - - return &lavalink.nodes[0], nil + return lavalink.BestNodeFunc(lavalink.nodes) } // GetPlayer gets a player for a guild @@ -116,3 +127,11 @@ func (lavalink *Lavalink) GetPlayer(guild string) (*Player, error) { return p, nil } + +func BestNodeByLoad(n []*Node) (*Node, error) { + sort.SliceStable(n, func(i, j int) bool { + return n[i].load < n[j].load + }) + + return n[0], nil +} diff --git a/node.go b/node.go index d9cf3fa..d91151f 100644 --- a/node.go +++ b/node.go @@ -183,11 +183,12 @@ func (node *Node) CreatePlayer(guildID string, sessionID string, event VoiceServ } player := &Player{ - guildID: guildID, - manager: node.manager, - node: node, - handler: handler, - vol: 100, + guildID: guildID, + manager: node.manager, + node: node, + handler: handler, + vol: 100, + lastVoiceServerUpdate: event, } node.manager.players[guildID] = player diff --git a/player.go b/player.go index 66e3673..1562c7b 100644 --- a/player.go +++ b/player.go @@ -6,15 +6,16 @@ import ( // Player is a Lavalink player type Player struct { - guildID string - time int - position int - paused bool - vol int - track string - manager *Lavalink - node *Node - handler EventHandler + guildID string + time int + position int + paused bool + vol int + track string + manager *Lavalink + node *Node + handler EventHandler + lastVoiceServerUpdate VoiceServerUpdate } // GuildID returns this player's Guild ID @@ -173,9 +174,17 @@ func (player *Player) Forward(sessionID string, event VoiceServerUpdate) error { Event: &event, } + player.lastVoiceServerUpdate = event + return player.node.wsConn.WriteJSON(msg) } +func (player *Player) ChangeNode(node *Node) error { + player.node = node + + return player.PlayAt(player.track, player.position, 0) +} + // Destroy will destroy this player func (player *Player) Destroy() error { msg := basicMessage{