UNPKG

zyno-bot-addons

Version:

Create easily addons for Zyno Bot

361 lines (357 loc) 19.5 kB
const GuildChannel = require('./guildChannel.js'); const CategoryChannel = require('./categoryChannel.js'); const { validatePermission, getAddonPermission, getClient, getResolvableDate, validateURL, getVideoQualityMode, getRegion } = require('../../../utils/functions.js'); const { getMessageContent } = require('../../../utils/messageFunctions.js'); const scopes = require('../../../bitfields/scopes.js'); const { Readable } = require('stream'); const Save = require('../../save.js'); const MemberManager = require('../../managers/memberManager.js'); const MessageManager = require('../../managers/messageManager.js'); const ytstream = require('yt-stream'); const channelManager = require('../../managers/channelManager.js'); let client = null; class VoiceChannel extends GuildChannel{ constructor(data, addon, guild, structureHandler, cache){ super(data, addon, guild); if(cache){ const addonChannelManager = channelManager.get(addon.name) || new Save(); const guildChannelManager = addonChannelManager.get(guild.id) || new Save(); guildChannelManager.set(data.id, this); addonChannelManager.set(guild.id, guildChannelManager); channelManager.set(addon.name, addonChannelManager); } if(!client) client = getClient(); this.addon = addon; this.joinable = data.joinable; this.speakable = data.speakable; this.full = data.full; this.rtcRegion = data.rtcRegion; this.bitrate = data.bitrate; this.userLimit = data.userLimit; this.videoQuality = data.videoQualityMode === 2 ? 'Full' : 'Auto'; if(validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)){ addon.channels.set(this.id, this); } this.deleteMessages = function(amount, filter){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.MESSAGES)) return reject(`Missing messages scope in bitfield`); if(typeof amount !== 'number') return reject('Amount argument must be a type of number'); if(amount < 1) amount = 1; else if(amount > 100) amount = 100; let messageDelete = amount; if(typeof filter === 'function'){ messageDelete = Array.from(this.messages.filter(m => filter(m)).values()).map(m => m.id).slice(0, amount); } data.bulkDelete(messageDelete).then(() => resolve()).catch(reject); }); } this.update = function(){ return new Promise((resolve, reject) => { data.fetch().then(ch => { resolve(structureHandler.createStructure('VoiceChannel', [ch, addon, guild])); }).catch(reject); }); } this.edit = function(options){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(typeof options !== 'object') return reject('Object argument must be a type of object'); let slowMode = undefined; if(typeof options.slowMode === 'number' || typeof options.slowMode === 'string' || options.slowMode instanceof Date){ const currentTimestamp = new Date().getTime(); slowMode = options.slowMode instanceof Date ? options.slowMode.getTime() - currentTimestamp : getResolvableDate(options.slowMode); slowMode = Math.round(slowMode / 1000); } data.edit({ name: typeof options.name === 'string' ? options.name : undefined, position: typeof options.position === 'number' ? options.position: undefined, nsfw: typeof options.nsfw === 'boolean' ? options.nsfw: undefined, parent: typeof options.parent === 'string' || options.parent instanceof CategoryChannel ? (typeof options.parent === 'string' ? options.parent : options.parent.id) : undefined, reason: typeof options.reason === 'string' ? options.reason : undefined, bitrate: typeof options.bitrate === 'number' ? options.bitrate : undefined, userLimit: typeof options.userLimit === 'number' ? (options.userLimit < 0 ? 0 : (options.userLimit > 99 ? 99 : options.userLimit)) : undefined, rateLimitPerUser: slowMode, videoQualityMode: typeof options.videoQuality === 'string' || typeof options.videoQuality === 'number' ? getVideoQualityMode(options.videoQuality) : undefined, rtcRegion: typeof options.rtcRegion === 'string' || options.rtcRegion === null ? (typeof options.rtcRegion === 'string' ? getRegion(options.rtcRegion) : options.rtcRegion) : undefined, permissionOverwrites: Array.isArray(options.permissions) ? options.permissions.reduce((arr, i) => { if(typeof i !== 'object' || Array.isArray(i) || i === null) return arr; if(typeof i.id !== 'string') return arr; if(!Array.isArray(i['allow']) && !Array.isArray(i['deny'])) return arr; if(typeof i['type'] === 'string'){ switch(i['type'].toLowerCase()){ case 'user': i['type'] = 1; break; case 'member': i['type'] = 1; break; case 'role': i['type'] = 0; break; default: delete i['type']; break; } } arr.push(i); return arr; }, []) : undefined }).then(ch => { resolve(structureHandler.createStructure('VoiceChannel', [ch, addon, guild])); }).catch(reject); }); } this.setRtcRegion = function(region, reason){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(typeof region !== 'string' && region !== null) return reject('Region must be a type of string or null'); if(typeof reason !== 'string') reason = undefined; region = getRegion(region); data.setRTCRegion(region, reason).then(ch => resolve(structureHandler.createStructure('VoiceChannel', [ch, addon, guild]))).catch(reject); }); } this.setUserLimit = function(limit, reason){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(typeof limit !== 'number') return reject('Limit must be a type of number'); if(typeof reason !== 'string') reason = undefined; if(limit < 0) limit = 0; else if(limit > 99) limit = 99; data.setUserLimit(limit, reason).then(ch => resolve(structureHandler.createStructure('VoiceChannel', [ch, addon, guild]))).catch(reject); }); } this.setVideoQuality = function(qualityMode, reason){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(typeof qualityMode !== 'number' && qualityMode !== 'string') return reject('Quality mode must be a type of number or type of string'); if(typeof reason !== 'string') reason = undefined; qualityMode = getVideoQualityMode(qualityMode); data.setVideoQualityMode(qualityMode, reason).then(ch => resolve(structureHandler.createStructure('VoiceChannel', [ch, addon, guild]))).catch(reject); }); } this.setBitrate = function(bitrate, reason){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(typeof bitrate !== 'number') return reject('Bitrate argument must be a type of number'); if(typeof reason !== 'string') reason = undefined; data.setBitrate(bitrate, reason).then(ch => resolve(structureHandler.createStructure('VoiceChannel', [ch, addon, guild]))).catch(reject); }); } this.send = function(...content){ return new Promise((resolve, reject) => { if(content.length === 0) return reject(`At least one argument must be given`); let _content = getMessageContent(content); data.send(_content).then(msg => { resolve(structureHandler.createStructure('Message', [msg, addon])); }).catch(reject); }); } this.playSong = function(stream){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(typeof stream !== 'string' && !(stream instanceof Readable)) return reject('Stream must be a type of string or instance of readable stream'); if(typeof stream === 'string'){ if(validateURL(stream)){ client.audioManager.play(data, stream, { quality: 'high', volume: 10 }).then(() => resolve()).catch(reject); } else { var query = stream.slice(0, 50).split("`").join(""); ytstream.search(query).then(res => { if(res.length === 0) return reject('There were no YouTube video\'s found with this query'); client.audioManager.play(res[0].url, stream, { quality: 'high', volume: 10 }).then(() => resolve()).catch(reject); }).catch(reject); } } else { client.audioManager.play(data, stream, { quality: 'high', volume: 10 }).then(() => resolve()).catch(reject); } }); } this.disconnect = function(){ return new Promise(async (resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); try{ await client.audioManager.stop(data); resolve(); } catch(err) { reject(err); } }); } this.getQueue = function(){ return new Promise(async (resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve([]); try{ const queue = client.audioManager.queue(data); resolve(queue); } catch(err) { reject(err); } }); } this.skipSong = function(){ return new Promise(async (resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); try{ await client.audioManager.skip(data); resolve(); } catch(err) { reject(err); } }); } this.previousSong = function(){ return new Promise(async (resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); try{ await client.audioManager.previous(data); resolve(); } catch(err) { reject(err); } }); } this.pauseSong = function(){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); try{ client.audioManager.pause(data); resolve(); } catch(err) { reject(err); } }); } this.resumeSong = function(){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); try{ client.audioManager.resume(data); resolve(); } catch(err) { reject(err); } }); } this.shuffle = function(){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); try{ client.audioManager.shuffle(data); resolve(); } catch(err) { reject(err); } }); } this.setLoop = function(){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); try{ client.audioManager.loop(data, client.audioManager.looptypes.loop); resolve(); } catch(err) { reject(err); } }); } this.setUnloop = function(){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); try{ client.audioManager.loop(data, client.audioManager.looptypes.off); resolve(); } catch(err) { reject(err); } }); } this.setQueueloop = function(){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); try{ client.audioManager.loop(data, client.audioManager.looptypes.queueloop); resolve(); } catch(err) { reject(err); } }); } this.setVolume = function(volume){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(typeof volume !== 'number') return reject('Volume argument must be a type of number'); if(volume > 10) volume = 10; else if(volume < 1) volume = 1; if(!data.guild.members.me.voice.channel) return resolve(); try{ client.audioManager.volume(data, volume); resolve(); } catch(err) { reject(err); } }); } this.getStream = function(){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); if(!data.guild.members.me.voice.channel) return resolve(); let stream = client.audioManager.getStream(data); resolve(stream); }); } this.isPlaying = function(){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); resolve(client.audioManager.isPlaying(data)); }); } this.getSongInfo = function(){ return new Promise((resolve, reject) => { if(!validatePermission(getAddonPermission(addon.name), scopes.bitfield.CHANNELS)) return reject(`Missing channels scope in bitfield`); resolve({...client.audioManager.getCurrentSong(data), filters: client.audioManager.getFilters(data)}); }); } } get messages(){ const addonMessageManager = MessageManager.get(this.addon.name) || new Save(); const guildMessageManager = addonMessageManager.get(this.guildId) || new Save(); const channelMessageManager = guildMessageManager.get(this.id) || new Save(); return channelMessageManager; } get members(){ let members = new Save(); const getGuild = client.guilds.cache.get(this.guildId); if(!getGuild) return members; const getChannel = getGuild.channels.cache.get(this.id); if(!getChannel) return members; const joinedMembers = Array.from(getChannel.members.values()); const addonMemberManager = MemberManager.get(this.addon.name) || new Save(); for(var i = 0; i < joinedMembers.length; i++){ var joinedMember = joinedMembers[i]; var cachedMemberGuilds = addonMemberManager.get(joinedMember.id) || new Save(); var cachedMember = cachedMemberGuilds.get(this.guildId); if(!cachedMember) continue; members.set(cachedMember.id, cachedMember); }; return members; } } module.exports = VoiceChannel;