diff --git a/lib/Logic/ChatHandler.js b/lib/Logic/ChatHandler.js index 731c58a..a0192f0 100644 --- a/lib/Logic/ChatHandler.js +++ b/lib/Logic/ChatHandler.js @@ -149,8 +149,9 @@ class DiscordieChatHandler extends ChatHandler { super(manager); this.bot = bot; - this.permissions.MANAGE_PERMISSIONS = Discordie.Permissions.General.MANAGE_ROLES; - this.permissions.VOICE_MUTE = Discordie.Permissions.Voice.MUTE_MEMBERS; + //TODO fix + this.permissions.MANAGE_PERMISSIONS = 1 << 3;//Discordie.Permissions.General.MANAGE_ROLES; + this.permissions.VOICE_MUTE = 1 << 22;//Discordie.Permissions.Voice.MUTE_MEMBERS; } register() { diff --git a/lib/Logic/InternalDJ.js b/lib/Logic/InternalDJ.js index 206092f..3b56fc2 100644 --- a/lib/Logic/InternalDJ.js +++ b/lib/Logic/InternalDJ.js @@ -1 +1 @@ -"use strict"; var Discordie = require('discordie'); var child_process = require('child_process'); class InternalDJ { constructor(bot, voiceConnection, wrapper, handler) { this.bot = bot; this.wrapper = wrapper; this.handler = handler; /* TODO: use it in the future */ this.voiceConnection = voiceConnection; this.playable = null; this.musicQueue = []; this.encoderCmd = null; this.cmdCache = null; this.process = null; this.stream = null; this.encoder = null; this.multithreaded = false; this.stopping = false; this.disconnectedEvent = function(info) { if(info.voiceConnection == this.voiceConnection) this.destroy(); }.bind(this); this.bot.Dispatcher.on(Discordie.Events.VOICE_DISCONNECTED, this.disconnectedEvent); } getCommand() { if(this.cmdCache != null) return this.cmdCache; var cmds = ["avconv", "ffmpeg", "avconv.exe", "ffmpeg.exe"]; if(this.encoderCmd != null) { cmds.unshift(this.encoderCmd); } else { cmds.unshift(process.cwd() + 'ffmpeg/ffmpeg'); cmds.unshift(process.cwd() + 'ffmpeg/ffmpeg.exe'); } for(var i = 0; i < cmds.length; i++){ var p = child_process.spawnSync(cmds[i]); if(!p.error) { this.cmdCache = cmds[i]; return cmds[i]; } } return null; } destroy() { this.bot.Dispatcher.removeListener(Discordie.Events.VOICE_DISCONNECTED, this.disconnectedEvent); } encodeStream(stream, sampleRate, channels) { if(this.process != null) { this.process.kill(); } var command = this.getCommand(); if(command == null) { console.log('The encoder was not found.'); this.destroy(); return null; } this.process = child_process.spawn(command, [ "-f", "s16le", "-ar", sampleRate, "-ac", channels, "-af", "volume=1", "pipe:1", "-i", "-" ]); stream.pipe(this.process.stdin); return this.process.stdout; } playStream(stream, sampleRate, channels, bitDepth) { var options = { frameDuration: 60, sampleRate: sampleRate, channels: channels, float: false, multiThreadedVoice: this.multithreaded }; var readSize = sampleRate / 1000 * options.frameDuration * bitDepth / 8 * channels; var process = this.process; var playable = this.playable; stream.once('readable', function() { if(this.playable != playable) return; this.encoder = this.voiceConnection.getEncoder(options); if(this.encoder == null) return; this.encoder.onNeedBuffer = function() { if(this.stopping) return; if(process == null || process.killed) return; if(this.playable != playable) return this.stop(); if(stream == null) return; var chunk = stream.read(readSize); if(!chunk) return setTimeout(this.encoder.onNeedBuffer, options.frameDuration); var sampleCount = readSize / channels / (bitDepth / 8); this.encoder.enqueue(chunk, sampleCount); }.bind(this); this.encoder.onNeedBuffer(); }.bind(this)); } play(playable) { this.stop(); this.playable = playable; var sampleRate = 48000; var bitDepth = 16; var channels = 2; playable.createStream().then(function(stream) { if(this.playable != playable) return; this.stream = stream; var encodedStream = this.encodeStream(this.stream, sampleRate, channels); encodedStream.once('end', function() { if(this.stopping) return; if(this.playable != playable) return; this.playable = null; this.stream = null; this.skip(); }.bind(this)); encodedStream.once('readable', function() { if(this.playable != playable) return; this.wrapper.emit('play'); }.bind(this)); this.playStream(encodedStream, sampleRate, channels, bitDepth); }.bind(this), function(error) { console.log("Music skipped by an error: " + error); this.skip(); }.bind(this)); } stop() { if(this.stopping) return; this.stopping = true; try { if(this.encoder != null) { this.encoder.kill(); } if(this.stream != null) { if(this.process != null) this.stream.unpipe(this.process.stdin); if(this.stream.end) this.stream.end(); if(this.stream.destroy) this.stream.destroy(); this.stream = null; } if(this.process != null) { this.process.stdin.pause(); this.process.kill(); this.process = null; } } catch(e) { console.log("An error ocurred while stopping the current music: " + e); } this.stopping = false; } skip() { this.stop(); if(this.playable != null) { this.playable.removeAllListeners('data-changed'); this.playable = null; } this.wrapper.emit('skip'); if(this.playable == null && this.musicQueue.length > 0) { this.play(this.musicQueue.shift()); } } addToQueue(playable) { var self = this; playable.on('data-changed', function() { self.wrapper.emit('data-changed'); }); playable.loadData(); if(this.playable == null) { this.play(playable); } else { this.musicQueue.push(playable); } } } module.exports = InternalDJ; \ No newline at end of file +"use strict"; var Discordie = require('discordie'); var child_process = require('child_process'); class InternalDJ { constructor(bot, voiceConnection, wrapper, handler) { this.bot = bot; this.wrapper = wrapper; this.handler = handler; /* TODO: use it in the future */ this.voiceConnection = voiceConnection; this.playable = null; this.musicQueue = []; this.encoderCmd = null; this.cmdCache = null; this.process = null; this.stream = null; this.encoder = null; this.multithreaded = false; this.stopping = false; this.disconnectedEvent = function(info) { if(info.voiceConnection == this.voiceConnection) this.destroy(); }.bind(this); this.bot.Dispatcher.on(Discordie.Events.VOICE_DISCONNECTED, this.disconnectedEvent); } getCommand() { if(this.cmdCache != null) return this.cmdCache; var cmds = ["avconv", "ffmpeg", "avconv.exe", "ffmpeg.exe"]; if(this.encoderCmd != null) { cmds.unshift(this.encoderCmd); } else { cmds.unshift(process.cwd() + '/ffmpeg/ffmpeg'); cmds.unshift(process.cwd() + '/ffmpeg/ffmpeg.exe'); } for(var i = 0; i < cmds.length; i++){ var p = child_process.spawnSync(cmds[i]); if(!p.error) { this.cmdCache = cmds[i]; return cmds[i]; } } return null; } destroy() { this.bot.Dispatcher.removeListener(Discordie.Events.VOICE_DISCONNECTED, this.disconnectedEvent); } encodeStream(stream, sampleRate, channels) { if(this.process != null) { this.process.kill(); } var command = this.getCommand(); if(command == null) { console.log('The encoder was not found.'); this.destroy(); return null; } this.process = child_process.spawn(command, [ "-f", "s16le", "-ar", sampleRate, "-ac", channels, "-af", "volume=1", "pipe:1", "-i", "-" ]); stream.pipe(this.process.stdin); return this.process.stdout; } playStream(stream, sampleRate, channels, bitDepth) { var options = { frameDuration: 60, sampleRate: sampleRate, channels: channels, float: false, multiThreadedVoice: this.multithreaded }; var readSize = sampleRate / 1000 * options.frameDuration * bitDepth / 8 * channels; var process = this.process; var playable = this.playable; stream.once('readable', function() { if(this.playable != playable) return; this.encoder = this.voiceConnection.getEncoder(options); if(this.encoder == null) return; this.encoder.onNeedBuffer = function() { if(this.stopping) return; if(process == null || process.killed) return; if(this.playable != playable) return this.stop(); if(stream == null) return; var chunk = stream.read(readSize); if(!chunk) return setTimeout(this.encoder.onNeedBuffer, options.frameDuration); var sampleCount = readSize / channels / (bitDepth / 8); this.encoder.enqueue(chunk, sampleCount); }.bind(this); this.encoder.onNeedBuffer(); }.bind(this)); } play(playable) { this.stop(); this.playable = playable; var sampleRate = 48000; var bitDepth = 16; var channels = 2; playable.createStream().then(function(stream) { if(this.playable != playable) return; this.stream = stream; var encodedStream = this.encodeStream(this.stream, sampleRate, channels); encodedStream.once('end', function() { if(this.stopping) return; if(this.playable != playable) return; this.playable = null; this.stream = null; this.skip(); }.bind(this)); encodedStream.once('readable', function() { if(this.playable != playable) return; this.wrapper.emit('play'); }.bind(this)); this.playStream(encodedStream, sampleRate, channels, bitDepth); }.bind(this), function(error) { console.log("Music skipped by an error: " + error); this.skip(); }.bind(this)); } stop() { if(this.stopping) return; this.stopping = true; try { if(this.encoder != null) { this.encoder.kill(); } if(this.stream != null) { if(this.process != null) this.stream.unpipe(this.process.stdin); if(this.stream.end) this.stream.end(); if(this.stream.destroy) this.stream.destroy(); this.stream = null; } if(this.process != null) { this.process.stdin.pause(); this.process.kill(); this.process = null; } } catch(e) { console.log("An error ocurred while stopping the current music: " + e); } this.stopping = false; } skip() { this.stop(); if(this.playable != null) { this.playable.removeAllListeners('data-changed'); this.playable = null; } this.wrapper.emit('skip'); if(this.playable == null && this.musicQueue.length > 0) { this.play(this.musicQueue.shift()); } } addToQueue(playable) { var self = this; playable.on('data-changed', function() { self.wrapper.emit('data-changed'); }); playable.loadData(); if(this.playable == null) { this.play(playable); } else { this.musicQueue.push(playable); } } } module.exports = InternalDJ; \ No newline at end of file diff --git a/package.json b/package.json index 88fb00f..4cb139b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "discord-dj", "description": "Discord DJ Bot. Let you play music in your server. Inspired by PlugDJ", - "version": "0.0.2", + "version": "0.0.3", "main": "lib/index.js", "author": "Guichaguri", "license": "LGPL-2.0", diff --git a/setup-bot.sh b/setup-bot.sh index 764f7c7..9dc5347 100755 --- a/setup-bot.sh +++ b/setup-bot.sh @@ -11,7 +11,7 @@ function npmError { echo "NPM was not found. Please, install Node.js and NPM" echo "http://nodejs.org" echo "" - + end } diff --git a/start-bot.sh b/start-bot.sh index 67ce69c..70e5962 100755 --- a/start-bot.sh +++ b/start-bot.sh @@ -1,3 +1,4 @@ #!/usr/bin/env bash + node ./runtime/DiscordDJ.js read -p "Press [Enter] to close..."