2021-04-06 17:58:46 +05:00
|
|
|
import { Message, Snowflake, VoiceConnection } from 'discord.js';
|
|
|
|
import AudioFilters from '../utils/AudioFilters';
|
2021-04-06 20:38:17 +05:00
|
|
|
import { Player } from '../Player';
|
2021-04-06 17:58:46 +05:00
|
|
|
import { EventEmitter } from 'events';
|
2021-04-06 20:38:17 +05:00
|
|
|
import { Track } from './Track';
|
2021-04-06 17:58:46 +05:00
|
|
|
import { QueueFilters } from '../types/types';
|
2021-04-04 22:36:40 +05:00
|
|
|
|
2021-04-06 20:38:17 +05:00
|
|
|
export class Queue extends EventEmitter {
|
2021-04-09 17:59:14 +05:00
|
|
|
/**
|
|
|
|
* The player that instantiated this Queue
|
|
|
|
*/
|
2021-04-04 22:36:40 +05:00
|
|
|
public player!: Player;
|
2021-04-06 17:55:29 +05:00
|
|
|
public guildID: Snowflake;
|
|
|
|
public voiceConnection?: VoiceConnection;
|
|
|
|
public stream?: any;
|
|
|
|
public tracks: Track[];
|
|
|
|
public previousTracks: Track[];
|
|
|
|
public stopped: boolean;
|
|
|
|
public lastSkipped: boolean;
|
|
|
|
public volume: number;
|
|
|
|
public paused: boolean;
|
|
|
|
public repeatMode: boolean;
|
|
|
|
public loopMode: boolean;
|
|
|
|
public filters: QueueFilters;
|
|
|
|
public additionalStreamTime: number;
|
|
|
|
public firstMessage: Message;
|
2021-04-21 10:08:33 +05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @type {boolean}
|
|
|
|
*/
|
2021-04-11 18:27:48 +05:00
|
|
|
public autoPlay = false;
|
2021-04-06 17:55:29 +05:00
|
|
|
|
2021-04-19 18:32:10 +05:00
|
|
|
/**
|
|
|
|
* Queue constructor
|
2021-04-21 10:08:33 +05:00
|
|
|
* @param {Player} player The player that instantiated this Queue
|
|
|
|
* @param {Discord.Message} message The message object
|
2021-04-19 18:32:10 +05:00
|
|
|
*/
|
2021-04-11 17:51:50 +05:00
|
|
|
constructor(player: Player, message: Message) {
|
2021-04-06 17:55:29 +05:00
|
|
|
super();
|
2021-04-04 22:36:40 +05:00
|
|
|
|
2021-04-06 17:58:46 +05:00
|
|
|
Object.defineProperty(this, 'player', { value: player, enumerable: false });
|
2021-04-06 17:55:29 +05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ID of the guild assigned to this queue
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {Discord.Snowflake}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.guildID = message.guild.id;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The voice connection of this queue
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {Discord.VoiceConnection}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.voiceConnection = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tracks of this queue
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {Track[]}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.tracks = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Previous tracks of this queue
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {Track[]}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.previousTracks = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If the player of this queue is stopped
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {boolean}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.stopped = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If last track was skipped
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {boolean}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.lastSkipped = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Queue volume
|
2021-04-21 11:52:59 +05:00
|
|
|
* @type {Number}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.volume = 100;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If the player of this queue is paused
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {boolean}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.paused = Boolean(this.voiceConnection?.dispatcher?.paused);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If repeat mode is enabled in this queue
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {boolean}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.repeatMode = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If loop mode is enabled in this queue
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {boolean}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.loopMode = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The additional calculated stream time
|
2021-04-21 11:52:59 +05:00
|
|
|
* @type {Number}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.additionalStreamTime = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The initial message object
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {Discord.Message}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
|
|
|
this.firstMessage = message;
|
|
|
|
|
2021-04-19 18:32:10 +05:00
|
|
|
/**
|
|
|
|
* The audio filters in this queue
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {QueueFilters}
|
2021-04-19 18:32:10 +05:00
|
|
|
*/
|
2021-04-06 17:55:29 +05:00
|
|
|
this.filters = {};
|
|
|
|
|
2021-04-06 17:58:46 +05:00
|
|
|
Object.keys(AudioFilters).forEach((fn) => {
|
2021-04-19 18:32:10 +05:00
|
|
|
this.filters[fn as keyof QueueFilters] = false;
|
2021-04-06 17:55:29 +05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Currently playing track
|
2021-04-21 10:08:33 +05:00
|
|
|
* @type {Track}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
2021-04-19 18:32:10 +05:00
|
|
|
get playing(): Track {
|
2021-04-06 17:55:29 +05:00
|
|
|
return this.tracks[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculated volume of this queue
|
2021-04-21 11:52:59 +05:00
|
|
|
* @type {Number}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
2021-04-19 18:32:10 +05:00
|
|
|
get calculatedVolume(): number {
|
2021-04-11 19:15:58 +05:00
|
|
|
return this.filters.normalizer ? this.volume + 70 : this.volume;
|
2021-04-06 17:55:29 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Total duration
|
2021-04-21 11:52:59 +05:00
|
|
|
* @type {Number}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
2021-04-19 18:32:10 +05:00
|
|
|
get totalTime(): number {
|
2021-04-06 17:55:29 +05:00
|
|
|
return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Current stream time
|
2021-04-21 11:52:59 +05:00
|
|
|
* @type {Number}
|
2021-04-06 17:55:29 +05:00
|
|
|
*/
|
2021-04-19 18:32:10 +05:00
|
|
|
get currentStreamTime(): number {
|
2021-04-06 17:55:29 +05:00
|
|
|
return this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0;
|
2021-04-04 22:36:40 +05:00
|
|
|
}
|
2021-04-17 19:28:12 +05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets audio filters in this player
|
2021-04-21 10:08:33 +05:00
|
|
|
* @param {QueueFilters} filters Audio filters to set
|
|
|
|
* @type {Promise<void>}
|
2021-04-17 19:28:12 +05:00
|
|
|
*/
|
2021-04-19 18:32:10 +05:00
|
|
|
setFilters(filters: QueueFilters): Promise<void> {
|
2021-04-17 19:28:12 +05:00
|
|
|
return this.player.setFilters(this.firstMessage, filters);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns array of all enabled filters
|
2021-04-21 11:52:59 +05:00
|
|
|
* @type {String[]}
|
2021-04-17 19:28:12 +05:00
|
|
|
*/
|
2021-04-19 18:32:10 +05:00
|
|
|
getFiltersEnabled(): string[] {
|
2021-04-17 19:28:12 +05:00
|
|
|
const filters: string[] = [];
|
|
|
|
|
|
|
|
for (const filter in this.filters) {
|
|
|
|
if (this.filters[filter as keyof QueueFilters] !== false) filters.push(filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
return filters;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns all disabled filters
|
2021-04-21 11:52:59 +05:00
|
|
|
* @type {String[]}
|
2021-04-17 19:28:12 +05:00
|
|
|
*/
|
2021-04-19 18:32:10 +05:00
|
|
|
getFiltersDisabled(): string[] {
|
2021-04-17 19:28:12 +05:00
|
|
|
const enabled = this.getFiltersEnabled();
|
|
|
|
|
|
|
|
return Object.keys(this.filters).filter((f) => !enabled.includes(f));
|
|
|
|
}
|
|
|
|
|
2021-04-19 18:32:10 +05:00
|
|
|
/**
|
|
|
|
* String representation of this Queue
|
2021-04-21 11:52:59 +05:00
|
|
|
* @type {String}
|
2021-04-19 18:32:10 +05:00
|
|
|
*/
|
|
|
|
toString(): string {
|
2021-04-17 19:28:12 +05:00
|
|
|
return `<Queue ${this.guildID}>`;
|
|
|
|
}
|
2021-04-04 22:44:45 +05:00
|
|
|
}
|
2021-04-06 20:38:17 +05:00
|
|
|
|
|
|
|
export default Queue;
|