diff --git a/src/main/java/net/Broken/Commandes/Music.java b/src/main/java/net/Broken/Commandes/Music.java index e38389a..019367f 100644 --- a/src/main/java/net/Broken/Commandes/Music.java +++ b/src/main/java/net/Broken/Commandes/Music.java @@ -5,6 +5,7 @@ import net.Broken.MainBot; import net.Broken.Outils.EmbedMessageUtils; import net.Broken.Outils.MessageTimeOut; import net.Broken.audio.AudioM; +import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.Message; import net.dv8tion.jda.core.entities.VoiceChannel; import net.dv8tion.jda.core.events.message.MessageReceivedEvent; @@ -18,8 +19,8 @@ import java.util.List; public class Music implements Commande { public AudioM audio; Logger logger = LogManager.getLogger(); - public Music() { - audio = new AudioM(); + public Music(Guild guild) { + audio = new AudioM(guild); } @Override diff --git a/src/main/java/net/Broken/Init.java b/src/main/java/net/Broken/Init.java index 4a942d5..cc80bd6 100644 --- a/src/main/java/net/Broken/Init.java +++ b/src/main/java/net/Broken/Init.java @@ -54,7 +54,7 @@ public class Init { MainBot.commandes.put("spam", new Spam()); MainBot.commandes.put("spaminfo", new SpamInfo()); MainBot.commandes.put("flush", new Flush()); - MainBot.commandes.put("music", new Music()); + MainBot.commandes.put("music", new Music(jda.getGuilds().get(0))); if (!dev) { MainBot.commandes.put("ass", new Ass()); diff --git a/src/main/java/net/Broken/RestApi/Data/CommandPostData.java b/src/main/java/net/Broken/RestApi/Data/CommandPostData.java index 741db3a..1de763c 100644 --- a/src/main/java/net/Broken/RestApi/Data/CommandPostData.java +++ b/src/main/java/net/Broken/RestApi/Data/CommandPostData.java @@ -3,5 +3,7 @@ package net.Broken.RestApi.Data; public class CommandPostData { public String command; - public String data; + public boolean onHead; + public String url; + public int playlistLimit; } diff --git a/src/main/java/net/Broken/RestApi/MusicWebController.java b/src/main/java/net/Broken/RestApi/MusicWebController.java index 7ef3410..65a97cb 100644 --- a/src/main/java/net/Broken/RestApi/MusicWebController.java +++ b/src/main/java/net/Broken/RestApi/MusicWebController.java @@ -1,6 +1,10 @@ package net.Broken.RestApi; +import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; +import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; +import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; +import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; import net.Broken.Commandes.Music; @@ -9,12 +13,13 @@ import net.Broken.RestApi.Data.CommandPostData; import net.Broken.RestApi.Data.CommandResponseData; import net.Broken.RestApi.Data.CurrentMusicData; import net.Broken.RestApi.Data.PlaylistData; +import net.Broken.audio.AudioM; import net.Broken.audio.NotConectedException; import net.Broken.audio.NullMusicManager; +import net.Broken.audio.WebLoadUtils; import net.dv8tion.jda.core.events.message.MessageReceivedEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.json.JSONObject; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; @@ -32,16 +37,22 @@ public class MusicWebController { @RequestMapping("/currentMusicInfo") public CurrentMusicData test(){ Music musicCommande = (Music) MainBot.commandes.get("music"); - try { - AudioPlayer player = musicCommande.audio.getMusicManager().player; - AudioTrack currentTrack = player.getPlayingTrack(); - if(currentTrack == null) - { + + if(musicCommande.audio.getGuild().getAudioManager().isConnected()){ + try { + AudioPlayer player = musicCommande.audio.getMusicManager().player; + AudioTrack currentTrack = player.getPlayingTrack(); + if(currentTrack == null) + { + return new CurrentMusicData(null,0, "STOP",false); + } + return new CurrentMusicData(currentTrack.getInfo(),currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused()); + } catch (NullMusicManager | NotConectedException nullMusicManager) { return new CurrentMusicData(null,0, "STOP",false); } - return new CurrentMusicData(currentTrack.getInfo(),currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused()); - } catch (NullMusicManager | NotConectedException nullMusicManager) { - return new CurrentMusicData(null,0, "STOP",false); + }else + { + return new CurrentMusicData(null,0, "DISCONNECTED",false); } } @@ -60,37 +71,40 @@ public class MusicWebController { @RequestMapping(value = "/command", method = RequestMethod.POST) public ResponseEntity command(@RequestBody CommandPostData data){ - if(data.command != null){ + if(data.command != null) { logger.info("receive command: " + data.command); Music musicCommande = (Music) MainBot.commandes.get("music"); - switch (data.command){ + switch (data.command) { case "PLAY": try { musicCommande.getAudioManager().getMusicManager().scheduler.resume(); - return new ResponseEntity<>(new CommandResponseData(data.command,"Accepted"), HttpStatus.OK); + return new ResponseEntity<>(new CommandResponseData(data.command, "Accepted"), HttpStatus.OK); } catch (NullMusicManager | NotConectedException nullMusicManager) { - return new ResponseEntity<>(new CommandResponseData(data.command,"Not connected to vocal!"), HttpStatus.NOT_ACCEPTABLE); + return new ResponseEntity<>(new CommandResponseData(data.command, "Not connected to vocal!"), HttpStatus.NOT_ACCEPTABLE); } case "PAUSE": try { musicCommande.getAudioManager().getMusicManager().scheduler.pause(); - return new ResponseEntity<>(new CommandResponseData(data.command,"Accepted"), HttpStatus.OK); + return new ResponseEntity<>(new CommandResponseData(data.command, "Accepted"), HttpStatus.OK); } catch (NullMusicManager | NotConectedException nullMusicManager) { - return new ResponseEntity<>(new CommandResponseData(data.command,"Not connected to vocal!"), HttpStatus.NOT_ACCEPTABLE); + return new ResponseEntity<>(new CommandResponseData(data.command, "Not connected to vocal!"), HttpStatus.NOT_ACCEPTABLE); } case "NEXT": try { musicCommande.getAudioManager().getMusicManager().scheduler.nextTrack(); - return new ResponseEntity<>(new CommandResponseData(data.command,"Accepted"), HttpStatus.OK); + return new ResponseEntity<>(new CommandResponseData(data.command, "Accepted"), HttpStatus.OK); } catch (NullMusicManager | NotConectedException nullMusicManager) { - return new ResponseEntity<>(new CommandResponseData(data.command,"Not connected to vocal!"), HttpStatus.NOT_ACCEPTABLE); + return new ResponseEntity<>(new CommandResponseData(data.command, "Not connected to vocal!"), HttpStatus.NOT_ACCEPTABLE); } case "STOP": musicCommande.getAudioManager().stop((MessageReceivedEvent) null); - return new ResponseEntity<>(new CommandResponseData(data.command,"Accepted"), HttpStatus.OK); + return new ResponseEntity<>(new CommandResponseData(data.command, "Accepted"), HttpStatus.OK); + + case "ADD": + return new WebLoadUtils(musicCommande ,data).getResponse(); } } @@ -98,4 +112,8 @@ public class MusicWebController { logger.info("Null"); return new ResponseEntity<>(new CommandResponseData(null, null), HttpStatus.NO_CONTENT); } + + + } + diff --git a/src/main/java/net/Broken/audio/AudioM.java b/src/main/java/net/Broken/audio/AudioM.java index 6ab75fe..216b0d3 100644 --- a/src/main/java/net/Broken/audio/AudioM.java +++ b/src/main/java/net/Broken/audio/AudioM.java @@ -31,28 +31,34 @@ public class AudioM { private int listTimeOut = 30; private int listExtremLimit = 300; private Logger logger = LogManager.getLogger(); + private Guild guild; - public AudioM() { + + + public AudioM(Guild guild) { this.playerManager = new DefaultAudioPlayerManager(); AudioSourceManagers.registerRemoteSources(playerManager); AudioSourceManagers.registerLocalSource(playerManager); + this.guild = guild; } - public void loadAndPlay(MessageReceivedEvent event, VoiceChannel voiceChannel, final String trackUrl,int playlistLimit,boolean onHead) { - GuildMusicManager musicManager = getGuildAudioPlayer(event.getGuild()); + public void loadAndPlay(MessageReceivedEvent event, VoiceChannel voiceChannel, final String trackUrl, int playlistLimit, boolean onHead) { + GuildMusicManager musicManager = getGuildAudioPlayer(guild); playedChanel = voiceChannel; playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() { @Override public void trackLoaded(AudioTrack track) { logger.info("Single Track detected!"); + Message message = event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Ajout de "+track.getInfo().title+" à la file d'attente!")).complete(); List messages = new ArrayList(){{ add(message); add(event.getMessage()); }}; new MessageTimeOut(messages, MainBot.messageTimeOut).start(); - play(event.getGuild(), voiceChannel, musicManager, track, onHead); + + play(guild, voiceChannel, musicManager, track, onHead); } @Override @@ -66,13 +72,10 @@ public class AudioM { add(event.getMessage()); }}; new MessageTimeOut(messages, MainBot.messageTimeOut).start(); - int i = 0; - for(AudioTrack track : playlist.getTracks()){ - play(event.getGuild(), voiceChannel, musicManager, track,onHead); - i++; - if((i>=playlistLimit && i!=-1) || i>listExtremLimit) - break; - } + + playListLoader(playlist, playlistLimit, onHead); + + } @@ -101,7 +104,15 @@ public class AudioM { }); } - + public void playListLoader(AudioPlaylist playlist,int playlistLimit, boolean onHead){ + int i = 0; + for(AudioTrack track : playlist.getTracks()){ + play(guild, playedChanel, musicManager, track, onHead); + i++; + if((i>=playlistLimit && i!=-1) || i>listExtremLimit) + break; + } + } private GuildMusicManager getGuildAudioPlayer(Guild guild) { @@ -114,7 +125,7 @@ public class AudioM { return musicManager; } - private void play(Guild guild, VoiceChannel channel, GuildMusicManager musicManager, AudioTrack track,boolean onHead) { + public void play(Guild guild, VoiceChannel channel, GuildMusicManager musicManager, AudioTrack track,boolean onHead) { if(!guild.getAudioManager().isConnected()) guild.getAudioManager().openAudioConnection(channel); if(!onHead) @@ -224,10 +235,9 @@ public class AudioM { public void stop (MessageReceivedEvent event) { musicManager.scheduler.stop(); - playedChanel = null; + musicManager.scheduler.flush(); if (event != null) { - event.getGuild().getAudioManager().closeAudioConnection(); Message message = event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Arret de la musique!")).complete(); List messages = new ArrayList(){{ add(message); @@ -253,6 +263,14 @@ public class AudioM { return musicManager; } + public Guild getGuild() { + return guild; + } - + public AudioPlayerManager getPlayerManager() { + return playerManager; + } + public VoiceChannel getPlayedChanel() { + return playedChanel; + } } diff --git a/src/main/java/net/Broken/audio/GuildMusicManager.java b/src/main/java/net/Broken/audio/GuildMusicManager.java index 40f9035..41ca494 100644 --- a/src/main/java/net/Broken/audio/GuildMusicManager.java +++ b/src/main/java/net/Broken/audio/GuildMusicManager.java @@ -24,7 +24,6 @@ public class GuildMusicManager { player = manager.createPlayer(); scheduler = new TrackScheduler(player); player.addListener(scheduler); - } /** diff --git a/src/main/java/net/Broken/audio/WebLoadUtils.java b/src/main/java/net/Broken/audio/WebLoadUtils.java new file mode 100644 index 0000000..7974e78 --- /dev/null +++ b/src/main/java/net/Broken/audio/WebLoadUtils.java @@ -0,0 +1,82 @@ +package net.Broken.audio; + +import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; +import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; +import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; +import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; +import com.sedmelluq.discord.lavaplayer.track.AudioTrack; +import net.Broken.Commandes.Music; +import net.Broken.RestApi.Data.CommandPostData; +import net.Broken.RestApi.Data.CommandResponseData; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.TreeMap; + +public class WebLoadUtils { + ResponseEntity response; + Logger logger = LogManager.getLogger(); + + public WebLoadUtils(Music musicCommande, CommandPostData data){ + AudioPlayerManager playerM = musicCommande.getAudioManager().getPlayerManager(); + try { + + AudioM audioM = musicCommande.getAudioManager(); + playerM.loadItemOrdered(musicCommande.getAudioManager().getMusicManager(), data.url, new AudioLoadResultHandler() { + @Override + public void trackLoaded(AudioTrack track) { + logger.info("Single Track detected from web!"); + + try { + audioM.play(audioM.getGuild(), audioM.getPlayedChanel(), audioM.getMusicManager(), track, data.onHead); + response = new ResponseEntity<>(new CommandResponseData("ADD", "Loaded"), HttpStatus.OK); + } catch (NullMusicManager | NotConectedException nullMusicManager) { + nullMusicManager.printStackTrace(); + } + + } + + @Override + public void playlistLoaded(AudioPlaylist playlist) { + + logger.info("Playlist detected from web! Limit: " + data.playlistLimit); + audioM.playListLoader(playlist,data.playlistLimit,data.onHead); + response = new ResponseEntity<>(new CommandResponseData("ADD", "Loaded"), HttpStatus.OK); + + } + + @Override + public void noMatches() { + logger.warn("Cant find media ! (web)"); + response = new ResponseEntity<>(new CommandResponseData("ADD", "Can't find media!"), HttpStatus.NOT_FOUND); + + } + + @Override + public void loadFailed(FriendlyException exception) { + logger.error("Cant load media ! (web)"); + response = new ResponseEntity<>(new CommandResponseData("ADD", "Cant load media !"), HttpStatus.INTERNAL_SERVER_ERROR); + + } + }); + while(response == null) + Thread.sleep(10); + + } catch (NullMusicManager | NotConectedException | InterruptedException nullMusicManager) { + nullMusicManager.printStackTrace(); + } + } + + public ResponseEntity getResponse(){ + while(response == null) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return response; + } +} diff --git a/src/main/resources/static/img/disconnected.png b/src/main/resources/static/img/disconnected.png new file mode 100644 index 0000000..2dc534e Binary files /dev/null and b/src/main/resources/static/img/disconnected.png differ diff --git a/src/main/resources/static/img/no_music.jpg b/src/main/resources/static/img/no_music.jpg index d0e8aae..0c61b1a 100644 Binary files a/src/main/resources/static/img/no_music.jpg and b/src/main/resources/static/img/no_music.jpg differ diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 8207e20..18c00be 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -3,7 +3,7 @@ - Starter Template - Materialize + Discord Bot @@ -15,23 +15,23 @@
-
-
-
- -
-

-
-
-
-
-
- -
- - -
-
-
-
    - -
-
- - -
- - - - - - -
- diff --git a/src/main/resources/static/js/init.js b/src/main/resources/static/js/init.js index c397607..a92afbd 100644 --- a/src/main/resources/static/js/init.js +++ b/src/main/resources/static/js/init.js @@ -17,21 +17,71 @@ $(document).ready(function() { $('#btn_play').click(function () { switch (state){ case "PLAYING": - sendCommand("PAUSE") + sendCommand(JSON.stringify({ command: "PAUSE"})) break; case "PAUSE": - sendCommand("PLAY") + sendCommand(JSON.stringify({ command: "PLAY"})) break; } }) $('#btn_next').click(function () { - sendCommand("NEXT"); + sendCommand(JSON.stringify({ command: "NEXT"})); }) $('#btn_stop').click(function () { - sendCommand("STOP"); + sendCommand(JSON.stringify({ command: "STOP"})); + }) + + $('.dropdown-button').dropdown({ + inDuration: 300, + outDuration: 225, + constrainWidth: false, // Does not change width of dropdown to that of the activator + hover: false, // Activate on hover + gutter: 0, // Spacing from edge + belowOrigin: false, // Displays dropdown below the button + alignment: 'left', // Displays dropdown with edge aligned to the left of button + stopPropagation: false // Stops event propagation + } + ); + + $('#input_link').on("input", function () { + if($('#input_link').val() == ""){ + if (!$('#btn_add_bottom').hasClass("disabled")) { + $('#btn_add_bottom').addClass("disabled"); + } + if (!$('#btn_add_top').hasClass("disabled")) { + $('#btn_add_top').addClass("disabled"); + } + } + else{ + if ($('#btn_add_bottom').hasClass("disabled")) { + $('#btn_add_bottom').removeClass("disabled"); + } + if ($('#btn_add_top').hasClass("disabled")) { + $('#btn_add_top').removeClass("disabled"); + } + } + }); + + $('#btn_add_top').click(function () { + var command = { + command: "ADD", + url: $('#input_link').val(), + playlistLimit: $('#limit_range').val(), + onHead: true + }; + sendCommand(JSON.stringify(command)); + }) + $('#btn_add_bottom').click(function () { + var command = { + command: "ADD", + url: $('#input_link').val(), + playlistLimit: $('#limit_range').val(), + onHead: false + }; + sendCommand(JSON.stringify(command)); }) }) @@ -50,7 +100,7 @@ function getCurentMusic() { state = data.state; switch (data.state) { case "STOP": - $('#music_text').text("No Music"); + $('#music_text').text("Connected on Vocal Channel"); if (!$('#btn_info').hasClass("indeterminate")) { $('#btn_info').addClass("determinate").removeClass("indeterminate"); @@ -64,6 +114,9 @@ function getCurentMusic() { if (!$('#btn_info').hasClass("disabled")) { $('#btn_info').addClass("disabled"); } + if ($('#add_btn').hasClass("disabled")) { + $('#add_btn').removeClass("disabled"); + } $('#music_img').attr("src","/img/no_music.jpg"); @@ -87,12 +140,41 @@ function getCurentMusic() { $('#btn_info').addClass("indeterminate").removeClass("determinate"); } break; + + case "DISCONNECTED": + $('#music_text').text("Disconnected from Vocal"); + + if (!$('#btn_info').hasClass("indeterminate")) { + $('#btn_info').addClass("determinate").removeClass("indeterminate"); + } + $('#music_progress').width("0%"); + + $('#btn_play').children().text("play_arrow"); + if (!$('#btn_play').hasClass("disabled")) { + $('#btn_play').addClass("disabled"); + } + if (!$('#btn_stop').hasClass("disabled")) { + $('#btn_stop').addClass("disabled"); + } + if (!$('#btn_next').hasClass("disabled")) { + $('#btn_next').addClass("disabled"); + } + if (!$('#btn_info').hasClass("disabled")) { + $('#btn_info').addClass("disabled"); + } + if (!$('#add_btn').hasClass("disabled")) { + $('#add_btn').addClass("disabled"); + } + + + $('#music_img').attr("src","/img/disconnected.png"); + break; } getPlayList(); }) .fail(function (data) { if(!error){ - alert("error"); + alert("Connection lost, I keep trying to refresh!"); error = true; } @@ -115,7 +197,6 @@ function getPlayList() { template.removeAttr("id"); template.removeAttr("style"); var content = template.html(); - console.log(content); content = content.replace("@title", element.title); content = content.replace("@author", element.author); content = content.replace("@lenght", msToTime(element.length)); @@ -156,13 +237,22 @@ function updateControl(data){ } $('#music_progress').width(percent + "%"); - + if ($('#btn_play').hasClass("disabled")) { + $('#btn_play').removeClass("disabled"); + } if ($('#btn_stop').hasClass("disabled")) { $('#btn_stop').removeClass("disabled"); } if ($('#btn_info').hasClass("disabled")) { $('#btn_info').removeClass("disabled"); } + if ($('#add_btn').hasClass("disabled")) { + $('#add_btn').removeClass("disabled"); + } + + if ($('#btn_next').hasClass("disabled")) { + $('#btn_next').removeClass("disabled"); + } $('#music_img').attr("src","http://img.youtube.com/vi/"+data.info.identifier+"/hqdefault.jpg"); updateModal(data); @@ -174,33 +264,29 @@ function sendCommand(commandStr){ dataType: 'json', contentType: 'application/json', url: "/api/music/command", - data: JSON.stringify({ command: commandStr}), + data: commandStr, success: function (data) { console.log(data); } }).fail(function (data) { console.log(data); + alert(data.responseJSON.Message); }); } function comparePlaylist(list1, list2){ if(list1 == null || list2 == null){ - console.log(list1); - console.log(list2); - console.log("False From null") return false; } if(list1.length != list2.length){ - console.log("False from length"); return false; } for(var i = 0; i++; i < list1.length){ if(list1[i].uri != list2[i].uri) - console.log("false from compare") return false } return true; diff --git a/src/main/resources/templates/music.html b/src/main/resources/templates/music.html index e58c4d2..556a45d 100644 --- a/src/main/resources/templates/music.html +++ b/src/main/resources/templates/music.html @@ -3,7 +3,7 @@ - Starter Template - Materialize + Discord Bot - Music Control @@ -15,23 +15,23 @@