UNPKG

fuga

Version:

A comprehensive, feature-rich, and modern Lavalink v4 client for Node.js

120 lines 4.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RaftLinkManager = void 0; const events_1 = require("events"); const RaftLinkNode_1 = require("./RaftLinkNode"); const RaftLinkPlayer_1 = require("./RaftLinkPlayer"); /** * The main hub for RaftLink, manages all nodes and players. */ class RaftLinkManager extends events_1.EventEmitter { nodes = new Map(); players = new Map(); userId = null; nodesToAdd; send; constructor(options) { super(); this.send = options.send; if (options.userId) this.userId = options.userId; if (options.nodes) { this.nodesToAdd = options.nodes; if (this.userId) this.addNodes(this.nodesToAdd); } } init(userId) { this.userId = userId; if (this.nodesToAdd) { this.addNodes(this.nodesToAdd); this.nodesToAdd = undefined; } } addNodes(nodes) { for (const nodeOptions of nodes) this.addNode(nodeOptions); } /** * Adds a new Lavalink node to the manager. * @param options The options for the node. */ addNode(options) { const identifier = options.identifier || options.host; console.log(`[RaftLink] [Manager] Adding node ${identifier}`); const node = new RaftLinkNode_1.RaftLinkNode(this, { ...options, identifier }); node.on('connect', () => this.emit('nodeConnect', node)); node.on('disconnect', (code, reason) => this.emit('nodeDisconnect', node, code, reason)); node.on('error', (err) => this.emit('nodeError', node, err)); node.on('reconnecting', () => this.emit('nodeReconnecting', node)); node.on('ready', (payload) => this.emit('nodeReady', node, payload)); node.connect(); this.nodes.set(identifier, node); return node; } /** * Creates a new player or returns an existing one. * @param options The options for creating a player. */ createPlayer(options) { const existingPlayer = this.players.get(options.guildId); if (existingPlayer) return existingPlayer; const node = this.getIdealNode(); if (!node) { console.error('[RaftLink] [Manager] No available nodes to create a player.'); throw new Error('No available Lavalink nodes to create a player.'); } console.log(`[RaftLink] [Manager] Creating player for guild ${options.guildId} on node ${node.options.identifier}`); const player = new RaftLinkPlayer_1.RaftLinkPlayer(node, options); this.players.set(options.guildId, player); return player; } /** * Forwards voice updates from your Discord library to the relevant player. * @param payload The raw voice state or server update payload. */ handleVoiceUpdate(payload) { console.log(`[RaftLink] [Manager] Received voice update payload:`, JSON.stringify(payload, null, 2)); const player = this.players.get(payload.guild_id); if (player) player.handleVoiceUpdate(payload); } /** * Searches for tracks using the best available node. * @param query The search query or URL. */ async search(query, requester, source) { const node = this.getIdealNode(); if (!node) throw new Error('No available Lavalink nodes to perform a search.'); const finalQuery = source ? `${source}:${query}` : query; const result = await node.rest.loadTracks(finalQuery); if (result.loadType === 'PLAYLIST_LOADED') { result.data.tracks = result.data.tracks.map((track) => ({ ...track, requester })); } else if (result.data) { result.data = result.data.map((track) => ({ ...track, requester })); } return result; } /** * Gets the most ideal node for new players based on player count and CPU load. * @returns The best available RaftLinkNode. */ getIdealNode() { return [...this.nodes.values()] .filter((node) => node.connected) .sort((a, b) => { const aStats = a.stats; const bStats = b.stats; if (!aStats || !aStats.cpu) return 1; if (!bStats || !bStats.cpu) return -1; return (aStats.cpu.lavalinkLoad / aStats.cpu.cores) * 100 - (bStats.cpu.lavalinkLoad / bStats.cpu.cores) * 100; })[0]; } } exports.RaftLinkManager = RaftLinkManager; //# sourceMappingURL=RaftLinkManager.js.map