documentation

This commit is contained in:
Snowflake107 2021-04-19 19:17:10 +05:45
parent 9e30219f8e
commit 4a345d8097
6 changed files with 249 additions and 55 deletions

View file

@ -80,7 +80,7 @@ export class Player extends EventEmitter {
} }
} }
static get AudioFilters() { static get AudioFilters(): typeof AudioFilters {
return AudioFilters; return AudioFilters;
} }
@ -89,7 +89,7 @@ export class Player extends EventEmitter {
* @param extractorName The extractor name * @param extractorName The extractor name
* @param extractor The extractor itself * @param extractor The extractor itself
*/ */
use(extractorName: string, extractor: any) { use(extractorName: string, extractor: any): Player {
if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError');
const methods = ['validate', 'getInfo']; const methods = ['validate', 'getInfo'];
@ -108,7 +108,7 @@ export class Player extends EventEmitter {
* Remove existing extractor from this player * Remove existing extractor from this player
* @param extractorName The extractor name * @param extractorName The extractor name
*/ */
unuse(extractorName: string) { unuse(extractorName: string): boolean {
if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError');
return this.Extractors.delete(extractorName); return this.Extractors.delete(extractorName);
@ -446,7 +446,7 @@ export class Player extends EventEmitter {
* Checks if this player is playing in a server * Checks if this player is playing in a server
* @param message The message object * @param message The message object
*/ */
isPlaying(message: Message) { isPlaying(message: Message): boolean {
return this.queues.some((g) => g.guildID === message.guild.id); return this.queues.some((g) => g.guildID === message.guild.id);
} }
@ -454,7 +454,7 @@ export class Player extends EventEmitter {
* Returns guild queue object * Returns guild queue object
* @param message The message object * @param message The message object
*/ */
getQueue(message: Message) { getQueue(message: Message): Queue {
return this.queues.find((g) => g.guildID === message.guild.id); return this.queues.find((g) => g.guildID === message.guild.id);
} }
@ -523,7 +523,7 @@ export class Player extends EventEmitter {
* @param time Time in ms to set * @param time Time in ms to set
* @alias setPosition * @alias setPosition
*/ */
seek(message: Message, time: number) { seek(message: Message, time: number): Promise<void> {
return this.setPosition(message, time); return this.setPosition(message, time);
} }
@ -553,7 +553,7 @@ export class Player extends EventEmitter {
* @param message The message object * @param message The message object
* @param channel New voice channel to move to * @param channel New voice channel to move to
*/ */
moveTo(message: Message, channel?: VoiceChannel) { moveTo(message: Message, channel?: VoiceChannel): boolean {
if (!channel || channel.type !== 'voice') return; if (!channel || channel.type !== 'voice') return;
const queue = this.queues.find((g) => g.guildID === message.guild.id); const queue = this.queues.find((g) => g.guildID === message.guild.id);
if (!queue) { if (!queue) {
@ -579,7 +579,7 @@ export class Player extends EventEmitter {
* Pause the playback * Pause the playback
* @param message The message object * @param message The message object
*/ */
pause(message: Message) { pause(message: Message): boolean {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -599,7 +599,7 @@ export class Player extends EventEmitter {
* Resume the playback * Resume the playback
* @param message The message object * @param message The message object
*/ */
resume(message: Message) { resume(message: Message): boolean {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -619,7 +619,7 @@ export class Player extends EventEmitter {
* Stops the player * Stops the player
* @param message The message object * @param message The message object
*/ */
stop(message: Message) { stop(message: Message): boolean {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -644,7 +644,7 @@ export class Player extends EventEmitter {
* @param message The message object * @param message The message object
* @param percent The volume percentage/amount to set * @param percent The volume percentage/amount to set
*/ */
setVolume(message: Message, percent: number) { setVolume(message: Message, percent: number): boolean {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -665,7 +665,7 @@ export class Player extends EventEmitter {
* Clears the queue * Clears the queue
* @param message The message object * @param message The message object
*/ */
clearQueue(message: Message) { clearQueue(message: Message): boolean {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -681,7 +681,7 @@ export class Player extends EventEmitter {
* Plays previous track * Plays previous track
* @param message The message object * @param message The message object
*/ */
back(message: Message) { back(message: Message): boolean {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -704,7 +704,7 @@ export class Player extends EventEmitter {
* @param message The message object * @param message The message object
* @param enabled If it should enable the repeat mode * @param enabled If it should enable the repeat mode
*/ */
setRepeatMode(message: Message, enabled: boolean) { setRepeatMode(message: Message, enabled: boolean): boolean {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -721,7 +721,7 @@ export class Player extends EventEmitter {
* @param message The message object * @param message The message object
* @param enabled If it should enable the loop mode * @param enabled If it should enable the loop mode
*/ */
setLoopMode(message: Message, enabled: boolean) { setLoopMode(message: Message, enabled: boolean): boolean {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -737,7 +737,7 @@ export class Player extends EventEmitter {
* Returns currently playing track * Returns currently playing track
* @param message The message object * @param message The message object
*/ */
nowPlaying(message: Message) { nowPlaying(message: Message): Track {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -751,7 +751,7 @@ export class Player extends EventEmitter {
* Shuffles the queue * Shuffles the queue
* @param message The message object * @param message The message object
*/ */
shuffle(message: Message) { shuffle(message: Message): Queue {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -775,7 +775,7 @@ export class Player extends EventEmitter {
* @param message The message object * @param message The message object
* @param track The track object/id to remove * @param track The track object/id to remove
*/ */
remove(message: Message, track: Track | number) { remove(message: Message, track: Track | number): Track {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) { if (!queue) {
this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message);
@ -803,7 +803,7 @@ export class Player extends EventEmitter {
* @param message The message object * @param message The message object
* @param queueTime If it should make the time code of the whole queue * @param queueTime If it should make the time code of the whole queue
*/ */
getTimeCode(message: Message, queueTime?: boolean) { getTimeCode(message: Message, queueTime?: boolean): { current: string; end: string } {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) return; if (!queue) return;
@ -827,7 +827,7 @@ export class Player extends EventEmitter {
* @param message The message object * @param message The message object
* @param options Progressbar options * @param options Progressbar options
*/ */
createProgressBar(message: Message, options?: PlayerProgressbarOptions) { createProgressBar(message: Message, options?: PlayerProgressbarOptions): string {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) return; if (!queue) return;
@ -876,14 +876,14 @@ export class Player extends EventEmitter {
* @example const lyrics = await player.lyrics("alan walker faded") * @example const lyrics = await player.lyrics("alan walker faded")
* message.channel.send(lyrics.lyrics); * message.channel.send(lyrics.lyrics);
*/ */
async lyrics(query: string) { async lyrics(query: string): Promise<LyricsData> {
const extractor = Util.require('@discord-player/extractor'); const extractor = Util.require('@discord-player/extractor');
if (!extractor) throw new PlayerError("Cannot call 'Player.lyrics()' without '@discord-player/extractor'"); if (!extractor) throw new PlayerError("Cannot call 'Player.lyrics()' without '@discord-player/extractor'");
const data = await extractor.Lyrics(query); const data = await extractor.Lyrics(query);
if (Array.isArray(data)) return null; if (Array.isArray(data)) return null;
return data as LyricsData; return data;
} }
/** /**
@ -931,7 +931,7 @@ export class Player extends EventEmitter {
}; };
} }
private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState) { private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState): void {
const queue = this.queues.find((g) => g.guildID === oldState.guild.id); const queue = this.queues.find((g) => g.guildID === oldState.guild.id);
if (!queue) return; if (!queue) return;
@ -964,7 +964,7 @@ export class Player extends EventEmitter {
} }
} }
private _addTrackToQueue(message: Message, track: Track) { private _addTrackToQueue(message: Message, track: Track): Queue {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) if (!queue)
this.emit( this.emit(
@ -978,7 +978,7 @@ export class Player extends EventEmitter {
return queue; return queue;
} }
private _addTracksToQueue(message: Message, tracks: Track[]) { private _addTracksToQueue(message: Message, tracks: Track[]): Queue {
const queue = this.getQueue(message); const queue = this.getQueue(message);
if (!queue) if (!queue)
throw new PlayerError( throw new PlayerError(
@ -1174,3 +1174,109 @@ export class Player extends EventEmitter {
} }
export default Player; export default Player;
/**
* Emitted when a track starts
* @event Player#trackStart
* @param {Discord.Message} message
* @param {Track} track
* @param {Queue} queue
*/
/**
* Emitted when a playlist is started
* @event Player#queueCreate
* @param {Discord.Message} message
* @param {Queue} queue
*/
/**
* Emitted when the bot is awaiting search results
* @event Player#searchResults
* @param {Discord.Message} message
* @param {string} query
* @param {Track[]} tracks
* @param {Discord.Collector} collector
*/
/**
* Emitted when the user has sent an invalid response for search results
* @event Player#searchInvalidResponse
* @param {Discord.Message} message
* @param {string} query
* @param {Track[]} tracks
* @param {string} invalidResponse
* @param {Discord.MessageCollector} collector
*/
/**
* Emitted when the bot has stopped awaiting search results (timeout)
* @event Player#searchCancel
* @param {Discord.Message} message
* @param {string} query
* @param {Track[]} tracks
*/
/**
* Emitted when the bot can't find related results to the query
* @event Player#noResults
* @param {Discord.Message} message
* @param {string} query
*/
/**
* Emitted when the bot is disconnected from the channel
* @event Player#botDisconnect
* @param {Discord.Message} message
*/
/**
* Emitted when the channel of the bot is empty
* @event Player#channelEmpty
* @param {Discord.Message} message
* @param {Queue} queue
*/
/**
* Emitted when the queue of the server is ended
* @event Player#queueEnd
* @param {Discord.Message} message
* @param {Queue} queue
*/
/**
* Emitted when a track is added to the queue
* @event Player#trackAdd
* @param {Discord.Message} message
* @param {Queue} queue
* @param {Track} track
*/
/**
* Emitted when a playlist is added to the queue
* @event Player#playlistAdd
* @param {Discord.Message} message
* @param {Queue} queue
* @param {Object} playlist
*/
/**
* Emitted when an error is triggered
* @event Player#error
* @param {string} error It can be `NotConnected`, `UnableToJoin`, `NotPlaying`, `ParseError`, `LiveVideo` or `VideoUnavailable`.
* @param {Discord.Message} message
*/
/**
* Emitted when discord-player attempts to parse playlist contents (mostly soundcloud playlists)
* @event Player#playlistParseStart
* @param {Object} playlist Raw playlist (unparsed)
* @param {Discord.Message} message The message
*/
/**
* Emitted when discord-player finishes parsing playlist contents (mostly soundcloud playlists)
* @event Player#playlistParseEnd
* @param {Object} playlist The playlist data (parsed)
* @param {Discord.Message} message The message
*/

View file

@ -4,13 +4,26 @@ class ExtractorModel {
name: string; name: string;
private _raw: any; private _raw: any;
/**
* Model for raw Discord Player extractors
* @param extractorName Name of the extractor
* @param data Extractor object
*/
constructor(extractorName: string, data: any) { constructor(extractorName: string, data: any) {
/**
* The extractor name
*/
this.name = extractorName; this.name = extractorName;
Object.defineProperty(this, '_raw', { value: data, configurable: false, writable: false, enumerable: false }); Object.defineProperty(this, '_raw', { value: data, configurable: false, writable: false, enumerable: false });
} }
async handle(query: string) { /**
* Method to handle requests from `Player.play()`
* @param query Query to handle
*/
async handle(query: string): Promise<ExtractorModelData> {
const data = await this._raw.getInfo(query); const data = await this._raw.getInfo(query);
if (!data) return null; if (!data) return null;
@ -23,18 +36,28 @@ class ExtractorModel {
author: data.author, author: data.author,
description: data.description, description: data.description,
url: data.url url: data.url
} as ExtractorModelData; };
} }
validate(query: string) { /**
* Method used by Discord Player to validate query with this extractor
* @param query The query to validate
*/
validate(query: string): boolean {
return Boolean(this._raw.validate(query)); return Boolean(this._raw.validate(query));
} }
get version() { /**
* The extractor version
*/
get version(): string {
return this._raw.version ?? '0.0.0'; return this._raw.version ?? '0.0.0';
} }
get important() { /**
* If player should mark this extractor as important
*/
get important(): boolean {
return Boolean(this._raw.important); return Boolean(this._raw.important);
} }
} }

View file

@ -26,6 +26,11 @@ export class Queue extends EventEmitter {
public firstMessage: Message; public firstMessage: Message;
public autoPlay = false; public autoPlay = false;
/**
* Queue constructor
* @param player The player that instantiated this Queue
* @param message The message object
*/
constructor(player: Player, message: Message) { constructor(player: Player, message: Message) {
super(); super();
@ -91,40 +96,41 @@ export class Queue extends EventEmitter {
*/ */
this.firstMessage = message; this.firstMessage = message;
// @ts-ignore /**
* The audio filters in this queue
*/
this.filters = {}; this.filters = {};
Object.keys(AudioFilters).forEach((fn) => { Object.keys(AudioFilters).forEach((fn) => {
// @ts-ignore this.filters[fn as keyof QueueFilters] = false;
this.filters[fn] = false;
}); });
} }
/** /**
* Currently playing track * Currently playing track
*/ */
get playing() { get playing(): Track {
return this.tracks[0]; return this.tracks[0];
} }
/** /**
* Calculated volume of this queue * Calculated volume of this queue
*/ */
get calculatedVolume() { get calculatedVolume(): number {
return this.filters.normalizer ? this.volume + 70 : this.volume; return this.filters.normalizer ? this.volume + 70 : this.volume;
} }
/** /**
* Total duration * Total duration
*/ */
get totalTime() { get totalTime(): number {
return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0; return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0;
} }
/** /**
* Current stream time * Current stream time
*/ */
get currentStreamTime() { get currentStreamTime(): number {
return this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0; return this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0;
} }
@ -132,14 +138,14 @@ export class Queue extends EventEmitter {
* Sets audio filters in this player * Sets audio filters in this player
* @param filters Audio filters to set * @param filters Audio filters to set
*/ */
setFilters(filters: QueueFilters) { setFilters(filters: QueueFilters): Promise<void> {
return this.player.setFilters(this.firstMessage, filters); return this.player.setFilters(this.firstMessage, filters);
} }
/** /**
* Returns array of all enabled filters * Returns array of all enabled filters
*/ */
getFiltersEnabled() { getFiltersEnabled(): string[] {
const filters: string[] = []; const filters: string[] = [];
for (const filter in this.filters) { for (const filter in this.filters) {
@ -152,13 +158,16 @@ export class Queue extends EventEmitter {
/** /**
* Returns all disabled filters * Returns all disabled filters
*/ */
getFiltersDisabled() { getFiltersDisabled(): string[] {
const enabled = this.getFiltersEnabled(); const enabled = this.getFiltersEnabled();
return Object.keys(this.filters).filter((f) => !enabled.includes(f)); return Object.keys(this.filters).filter((f) => !enabled.includes(f));
} }
toString() { /**
* String representation of this Queue
*/
toString(): string {
return `<Queue ${this.guildID}>`; return `<Queue ${this.guildID}>`;
} }
} }

View file

@ -1,23 +1,69 @@
import { Player } from '../Player'; import { Player } from '../Player';
import { User } from 'discord.js'; import { User } from 'discord.js';
import { TrackData } from '../types/types'; import { TrackData } from '../types/types';
import Queue from './Queue';
export class Track { export class Track {
/** /**
* The player that instantiated this Track * The player that instantiated this Track
*/ */
public player!: Player; public player!: Player;
/**
* Title of this track
*/
public title!: string; public title!: string;
/**
* Description of this track
*/
public description!: string; public description!: string;
/**
* Author of this track
*/
public author!: string; public author!: string;
/**
* Link of this track
*/
public url!: string; public url!: string;
/**
* Thumbnail of this track
*/
public thumbnail!: string; public thumbnail!: string;
/**
* Duration of this track
*/
public duration!: string; public duration!: string;
/**
* View count of this track
*/
public views!: number; public views!: number;
/**
* Person who requested this track
*/
public requestedBy!: User; public requestedBy!: User;
/**
* If this track belongs to a playlist
*/
public fromPlaylist!: boolean; public fromPlaylist!: boolean;
/**
* Raw data of this track
*/
public raw!: TrackData; public raw!: TrackData;
/**
* Track constructor
* @param player The player that instantiated this Track
* @param data Track data
*/
constructor(player: Player, data: TrackData) { constructor(player: Player, data: TrackData) {
Object.defineProperty(this, 'player', { value: player, enumerable: false }); Object.defineProperty(this, 'player', { value: player, enumerable: false });
@ -42,14 +88,14 @@ export class Track {
/** /**
* The queue in which this track is located * The queue in which this track is located
*/ */
get queue() { get queue(): Queue {
return this.player.queues.find((q) => q.tracks.includes(this)); return this.player.queues.find((q) => q.tracks.includes(this));
} }
/** /**
* The track duration in millisecond * The track duration in millisecond
*/ */
get durationMS() { get durationMS(): number {
const times = (n: number, t: number) => { const times = (n: number, t: number) => {
let tn = 1; let tn = 1;
for (let i = 0; i < t; i++) tn *= n; for (let i = 0; i < t; i++) tn *= n;
@ -63,7 +109,10 @@ export class Track {
.reduce((a, c) => a + c, 0); .reduce((a, c) => a + c, 0);
} }
toString() { /**
* String representation of this track
*/
toString(): string {
return `${this.title} by ${this.author}`; return `${this.title} by ${this.author}`;
} }
} }

View file

@ -145,3 +145,10 @@ export interface PlayerStats {
uptime: number; uptime: number;
}; };
} }
export interface TimeData {
days: number;
hours: number;
minutes: number;
seconds: number;
}

View file

@ -1,4 +1,4 @@
import { QueryType } from '../types/types'; import { QueryType, TimeData } from '../types/types';
import { FFmpeg } from 'prism-media'; import { FFmpeg } from 'prism-media';
import YouTube from 'youtube-sr'; import YouTube from 'youtube-sr';
import { Track } from '../Structures/Track'; import { Track } from '../Structures/Track';
@ -19,7 +19,7 @@ export class Util {
throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`);
} }
static getFFmpegVersion(force?: boolean) { static getFFmpegVersion(force?: boolean): string {
try { try {
const info = FFmpeg.getInfo(Boolean(force)); const info = FFmpeg.getInfo(Boolean(force));
@ -29,12 +29,12 @@ export class Util {
} }
} }
static checkFFmpeg(force?: boolean) { static checkFFmpeg(force?: boolean): boolean {
const version = Util.getFFmpegVersion(force); const version = Util.getFFmpegVersion(force);
return version === null ? false : true; return version === null ? false : true;
} }
static alertFFmpeg() { static alertFFmpeg(): void {
const hasFFmpeg = Util.checkFFmpeg(); const hasFFmpeg = Util.checkFFmpeg();
if (!hasFFmpeg) if (!hasFFmpeg)
@ -59,11 +59,11 @@ export class Util {
return 'youtube_search'; return 'youtube_search';
} }
static isURL(str: string) { static isURL(str: string): boolean {
return str.length < 2083 && attachmentRegex.test(str); return str.length < 2083 && attachmentRegex.test(str);
} }
static getVimeoID(query: string) { static getVimeoID(query: string): string {
return Util.getQueryType(query) === 'vimeo' return Util.getQueryType(query) === 'vimeo'
? query ? query
.split('/') .split('/')
@ -72,7 +72,7 @@ export class Util {
: null; : null;
} }
static parseMS(milliseconds: number) { static parseMS(milliseconds: number): TimeData {
const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil; const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil;
return { return {
@ -83,7 +83,7 @@ export class Util {
}; };
} }
static durationString(durObj: object) { static durationString(durObj: object): string {
return Object.values(durObj) return Object.values(durObj)
.map((m) => (isNaN(m) ? 0 : m)) .map((m) => (isNaN(m) ? 0 : m))
.join(':'); .join(':');
@ -119,7 +119,7 @@ export class Util {
}); });
} }
static isRepl() { static isRepl(): boolean {
if ('DP_REPL_NOCHECK' in process.env) return false; if ('DP_REPL_NOCHECK' in process.env) return false;
const REPL_IT_PROPS = [ const REPL_IT_PROPS = [
@ -137,11 +137,11 @@ export class Util {
return false; return false;
} }
static isVoiceEmpty(channel: VoiceChannel) { static isVoiceEmpty(channel: VoiceChannel): boolean {
return channel.members.filter((member) => !member.user.bot).size === 0; return channel.members.filter((member) => !member.user.bot).size === 0;
} }
static buildTimeCode(data: any) { static buildTimeCode(data: any): string {
const items = Object.keys(data); const items = Object.keys(data);
const required = ['days', 'hours', 'minutes', 'seconds']; const required = ['days', 'hours', 'minutes', 'seconds'];