All files / src/modules/bot/music/classes BaseManager.ts

0% Statements 0/40
0% Branches 0/4
0% Functions 0/20
0% Lines 0/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127                                                                                                                                                                                                                                                             
import { LavalinkManagerEvents, NodeManagerEvents } from "@/modules/bot/music/types/lavalink-client";
import { Config } from "@/modules/shared/config/types";
import { Logger } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { EventEmitter2 } from "@nestjs/event-emitter";
import { Client } from "discord.js";
import { LavalinkManager, ManagerQueueOptions } from "lavalink-client";
 
export class BaseManager extends LavalinkManager {
	public constructor(
		private readonly client: Client,
		private readonly config: ConfigService,
		private readonly eventEmitter: EventEmitter2,
		{ clientOptions, queueOptions, debugOptions }: Options,
	) {
		const logger = new Logger(clientOptions.username);
		super({
			nodes: [
				{
					regions: ["us-east", "us-central", "us-south", "us-west", "brazil"],
					id: "localhost",
					host: process.env.LavalinkHOST,
					port: 2333,
					authorization: process.env.LavalinkPassword,
					retryAmount: 22,
					retryDelay: 5000,
				},
			],
			client: {
				id: config.getOrThrow<Config["Discord"]>("Discord").Client.ID,
				username: clientOptions.username,
			},
			autoSkip: true,
			playerOptions: {
				applyVolumeAsFilter: false,
				clientBasedPositionUpdateInterval: 100,
				defaultSearchPlatform: "ytmsearch",
				volumeDecrementer: config.getOrThrow<Config["Music"]>("Music").Volumes.Lavalink,
				useUnresolvedData: true,
				onDisconnect: {
					autoReconnect: false,
					destroyPlayer: false,
				},
			},
			queueOptions,
			sendToShard(id, payload) {
				const guild = client.guilds.cache.get(id);
				if (!guild) {
					return logger.error("sendToShard - guild not found: ", id);
				}
				if (!guild.shard) {
					return logger.error("sendToShard - guild has no shard not found: ", guild);
				}
				return guild.shard.send(payload);
			},
			advancedOptions: {
				debugOptions,
			},
		});
 
		this.setMaxListeners(15);
		this.nodeManager.setMaxListeners(8);
 
		const LavalinkManagerEvents: Partial<LavalinkManagerEvents> = {
			trackStart: (player, track, payload) => this.eventEmitter.emit("track.start", player, track, payload),
			trackEnd: (player, track, payload) => this.eventEmitter.emit("track.end", player, track, payload),
			trackStuck: (player, track, payload) => this.eventEmitter.emit("track.stuck", player, track, payload),
			trackError: (player, track, payload) => this.eventEmitter.emit("track.error", player, track, payload),
			queueEnd: (player, track, payload) => this.eventEmitter.emit("queue.end", player, track, payload),
			playerCreate: (player) => this.eventEmitter.emit("player.create", player),
			playerMove: (player, oldVoiceChannelId, newVoiceChannelId) =>
				this.eventEmitter.emit("player.move", player, oldVoiceChannelId, newVoiceChannelId),
			playerDisconnect: (player, voiceChannelId) => this.eventEmitter.emit("player.disconnect", player, voiceChannelId),
			// playerSocketClosed: (player, payload) => this.eventEmitter.emit("player.socketClosed", player, payload),
			playerDestroy: (player, destroyReason) => this.eventEmitter.emit("player.destroy", player, destroyReason),
			// playerUpdate: (oldPlayerJson, newPlayer) => this.eventEmitter.emit("player.update", oldPlayerJson, newPlayer),
			// SegmentsLoaded: (player, track, payload) => this.eventEmitter.emit("segments.loaded", player, track, payload),
			// SegmentSkipped: (player, track, payload) => this.eventEmitter.emit("segments.skipped", player, track, payload),
			// ChapterStarted: (player, track, payload) => this.eventEmitter.emit("chapter.started", player, track, payload),
			// ChaptersLoaded: (player, track, payload) => this.eventEmitter.emit("chapter.loaded", player, track, payload),
		};
		const NodeManagerEvents: Partial<NodeManagerEvents> = {
			create: (node) => this.eventEmitter.emit("node.create", node, clientOptions.username),
			destroy: (node, destroyReason) =>
				this.eventEmitter.emit("node.destroy", node, destroyReason, clientOptions.username),
			connect: (node) => this.eventEmitter.emit("node.connect", node, clientOptions.username),
			reconnecting: (node) => this.eventEmitter.emit("node.reconnecting", node, clientOptions.username),
			disconnect: (node, reason) => this.eventEmitter.emit("node.disconnect", node, reason, clientOptions.username),
			error: (node, error, payload) =>
				this.eventEmitter.emit("node.error", node, error, payload, clientOptions.username),
			raw: (node, payload) => this.eventEmitter.emit("node.raw", node, payload, clientOptions.username),
			// resumed: (node, payload, players) =>
			// 	this.eventEmitter.emit("node.resumed", node, payload, players, clientOptions.username),
		};
 
		for (const event in LavalinkManagerEvents) {
			this.on(event as keyof LavalinkManagerEvents, LavalinkManagerEvents[event]);
		}
 
		for (const event in NodeManagerEvents) {
			this.nodeManager.on(event as keyof NodeManagerEvents, NodeManagerEvents[event]);
		}
 
		client.on("raw", (data) => {
			this.sendRawData(data);
		});
	}
 
	public async load(): Promise<void> {
		try {
			await this.init({ ...this.client.user });
		} catch (error) {
			console.log(error);
		}
	}
}
 
interface Options {
	clientOptions: {
		username: string;
	};
	queueOptions: ManagerQueueOptions;
	debugOptions?: {
		noAudio: boolean;
	};
}