From 010627a9b64479048a7a9959466d9f4d6a4a63db Mon Sep 17 00:00:00 2001 From: Sebastien Date: Sun, 12 Apr 2020 18:23:06 +0200 Subject: [PATCH] Auto flow is back online ! --- .../Broken/RestApi/MusicWebAPIController.java | 108 +++++++--------- src/main/java/net/Broken/audio/AudioM.java | 120 +++++++++--------- .../java/net/Broken/audio/TrackScheduler.java | 83 ++++++------ .../audio/Youtube/RelatedIdNotFound.java | 4 + .../audio/Youtube/YoutubeSearchRework.java | 19 +++ 5 files changed, 177 insertions(+), 157 deletions(-) create mode 100644 src/main/java/net/Broken/audio/Youtube/RelatedIdNotFound.java diff --git a/src/main/java/net/Broken/RestApi/MusicWebAPIController.java b/src/main/java/net/Broken/RestApi/MusicWebAPIController.java index 0bdfcfd..9f8886d 100644 --- a/src/main/java/net/Broken/RestApi/MusicWebAPIController.java +++ b/src/main/java/net/Broken/RestApi/MusicWebAPIController.java @@ -49,40 +49,36 @@ public class MusicWebAPIController { @RequestMapping("/currentMusicInfo") - public ResponseEntity getCurrentM(@RequestParam(value = "guild") String guildId){ //TODO security issue ???!!! + public ResponseEntity getCurrentM(@RequestParam(value = "guild") String guildId) { //TODO security issue ???!!! Guild guild = MainBot.jda.getGuildById(guildId); - if(guild == null ){ + if (guild == null) { logger.warn("Request whit no guild!"); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } - else{ + } else { logger.trace("currentMusicInfo for " + guild.getName()); } - if(guild.getAudioManager().isConnected()){ + if (guild.getAudioManager().isConnected()) { AudioPlayer player = AudioM.getInstance(guild).getGuildMusicManager().player; AudioTrack currentTrack = player.getPlayingTrack(); - if(currentTrack == null) - { - return new ResponseEntity<>(new CurrentMusicData(null,0, "STOP",false, AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()),HttpStatus.OK); + if (currentTrack == null) { + return new ResponseEntity<>(new CurrentMusicData(null, 0, "STOP", false, AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()), HttpStatus.OK); } UserAudioTrackData uat = new UserAudioTrackData(AudioM.getInstance(guild).getGuildMusicManager().scheduler.getCurrentPlayingTrack()); - return new ResponseEntity<>(new CurrentMusicData(uat, currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused(), AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()),HttpStatus.OK); - }else - { - return new ResponseEntity<>(new CurrentMusicData(null,0, "DISCONNECTED",false, false),HttpStatus.OK); + return new ResponseEntity<>(new CurrentMusicData(uat, currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused(), AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()), HttpStatus.OK); + } else { + return new ResponseEntity<>(new CurrentMusicData(null, 0, "DISCONNECTED", false, false), HttpStatus.OK); } } @RequestMapping("/getPlaylist") - public ResponseEntity getPlaylist(@RequestParam(value = "guild") String guildId){ //TODO security issue ???!!! + public ResponseEntity getPlaylist(@RequestParam(value = "guild") String guildId) { //TODO security issue ???!!! Guild guild = MainBot.jda.getGuildById(guildId); - if(guild == null ){ + if (guild == null) { logger.warn("Request whit no guild!"); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } - else{ + } else { logger.trace("getPlaylist for " + guild.getName()); } @@ -92,13 +88,11 @@ public class MusicWebAPIController { } - - @RequestMapping("/getAllInfo") - public ResponseEntity getAllInfo(@RequestParam(value = "guild") String guildId, @CookieValue("token") String token){ - if(token != null) { + public ResponseEntity getAllInfo(@RequestParam(value = "guild") String guildId, @CookieValue("token") String token) { + if (token != null) { Guild guild = MainBot.jda.getGuildById(guildId); - if(guild == null ){ + if (guild == null) { logger.warn("All info without guild!"); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); @@ -110,23 +104,20 @@ public class MusicWebAPIController { PlaylistData list = new PlaylistData(AudioM.getInstance(guild).getGuildMusicManager().scheduler.getList()); CurrentMusicData musicData; - if(guild.getAudioManager().isConnected()){ + if (guild.getAudioManager().isConnected()) { AudioPlayer player = AudioM.getInstance(guild).getGuildMusicManager().player; AudioTrack currentTrack = player.getPlayingTrack(); - if(currentTrack == null) - { - musicData = new CurrentMusicData(null,0, "STOP",false, AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()); - } - else{ + if (currentTrack == null) { + musicData = new CurrentMusicData(null, 0, "STOP", false, AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()); + } else { UserAudioTrackData uat = new UserAudioTrackData(AudioM.getInstance(guild).getGuildMusicManager().scheduler.getCurrentPlayingTrack()); musicData = new CurrentMusicData(uat, currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused(), AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()); } - }else - { - musicData = new CurrentMusicData(null,0, "DISCONNECTED",false, false); + } else { + musicData = new CurrentMusicData(null, 0, "DISCONNECTED", false, false); } - return new ResponseEntity<>(new AllMusicInfoData(musicData, list),HttpStatus.OK); + return new ResponseEntity<>(new AllMusicInfoData(musicData, list), HttpStatus.OK); } catch (UnknownTokenException e) { @@ -135,8 +126,7 @@ public class MusicWebAPIController { } - } - else{ + } else { logger.warn("All Info without token!"); return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); @@ -144,67 +134,63 @@ public class MusicWebAPIController { } @RequestMapping(value = "/command", method = RequestMethod.POST) - public ResponseEntity command(@RequestBody CommandPostData data, HttpServletRequest request, @RequestParam(value = "guild") String guildId, @CookieValue("token") String token){ + public ResponseEntity command(@RequestBody CommandPostData data, HttpServletRequest request, @RequestParam(value = "guild") String guildId, @CookieValue("token") String token) { - if(data.command != null) { - if(token != null) { + if (data.command != null) { + if (token != null) { Guild guild = MainBot.jda.getGuildById(guildId); - if(guild == null ){ + if (guild == null) { logger.warn("Request whit no guild!"); - return new ResponseEntity<>(new CommandResponseData(data.command,"Missing Guild!\nPlease Re-connect.","token"), HttpStatus.UNAUTHORIZED); + return new ResponseEntity<>(new CommandResponseData(data.command, "Missing Guild!\nPlease Re-connect.", "token"), HttpStatus.UNAUTHORIZED); } try { UserEntity user = userUtils.getUserWithApiToken(userRepository, token); - logger.info("Receive command " + data.command + " from " + request.getRemoteAddr() + " USER: " + user.getName() + " GUILD: " + guild.getName()); + logger.info("[" + guild.getName() + "] Receive command" + data.command + " from" + request.getRemoteAddr() + " USER:" + user.getName() + " GUILD:" + guild.getName()); if (ApiCommandLoader.apiCommands.containsKey(data.command)) { UserStatsUtils.getINSTANCE().addApiCount(user, guildId); return ApiCommandLoader.apiCommands.get(data.command).action(data, MainBot.jda.getUserById(user.getJdaId()), guild); - } - else + } else return new ResponseEntity<>(new CommandResponseData(data.command, "Unknown Command", "command"), HttpStatus.BAD_REQUEST); } catch (UnknownTokenException e) { - logger.warn("Command with unknown token from: "+request.getRemoteAddr()); - return new ResponseEntity<>(new CommandResponseData(data.command,"Unknown Token!\nPlease Re-connect.", "token"), HttpStatus.UNAUTHORIZED); + logger.warn("Command with unknown token from: " + request.getRemoteAddr()); + return new ResponseEntity<>(new CommandResponseData(data.command, "Unknown Token!\nPlease Re-connect.", "token"), HttpStatus.UNAUTHORIZED); } - } - else{ - logger.warn("Command without token! ip: "+ request.getRemoteAddr()); - return new ResponseEntity<>(new CommandResponseData(data.command,"Missing token!\nPlease Re-connect.","token"), HttpStatus.UNAUTHORIZED); + } else { + logger.warn("Command without token! ip: " + request.getRemoteAddr()); + return new ResponseEntity<>(new CommandResponseData(data.command, "Missing token!\nPlease Re-connect.", "token"), HttpStatus.UNAUTHORIZED); } - } - else + } else logger.info("Null"); return new ResponseEntity<>(new CommandResponseData(null, null), HttpStatus.NO_CONTENT); } @RequestMapping(value = "/getChanel", method = RequestMethod.GET) - public ResponseEntity> getChanel(@RequestParam(value = "guild") String guildId){ //TODO security issue ???!!! + public ResponseEntity> getChanel(@RequestParam(value = "guild") String guildId) { //TODO security issue ???!!! Guild guild = MainBot.jda.getGuildById(guildId); - if(guild == null ){ + if (guild == null) { logger.warn("Request whit no guild!"); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } - else{ + } else { logger.trace("getPlaylist for " + guild.getName()); } List temp = new ArrayList<>(); - for(VoiceChannel aChanel : GetVoiceChanels.find(guild)){ - temp.add(new ChanelData(aChanel.getName(),aChanel.getId(),aChanel.getPosition())); + for (VoiceChannel aChanel : GetVoiceChanels.find(guild)) { + temp.add(new ChanelData(aChanel.getName(), aChanel.getId(), aChanel.getPosition())); } return new ResponseEntity<>(temp, HttpStatus.OK); } @RequestMapping(value = "/search", method = RequestMethod.GET) - public ResponseEntity> search(@CookieValue(name = "token", defaultValue = "") String token, @RequestParam(value = "query") String query, @RequestParam(value = "playlist") boolean playlist ){ - if(token != null && !token.isEmpty()) { + public ResponseEntity> search(@CookieValue(name = "token", defaultValue = "") String token, @RequestParam(value = "query") String query, @RequestParam(value = "playlist") boolean playlist) { + if (token != null && !token.isEmpty()) { try { UserEntity user = userUtils.getUserWithApiToken(userRepository, token); // YoutubeTools youtubeTools = YoutubeTools.getInstance(); @@ -213,9 +199,9 @@ public class MusicWebAPIController { List result = youtubeSearch.searchVideo(query, 25, playlist); return new ResponseEntity<>(result, HttpStatus.OK); - }catch (UnknownTokenException e){ + } catch (UnknownTokenException e) { logger.warn("Search without token!"); - return new ResponseEntity<>( HttpStatus.UNAUTHORIZED); + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } catch (GoogleJsonResponseException e) { logger.error("There was a service error: " + e.getDetails().getCode() + " : " + e.getDetails().getMessage()); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); @@ -224,9 +210,9 @@ public class MusicWebAPIController { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } - }else{ + } else { logger.warn("Search without token!"); - return new ResponseEntity<>( HttpStatus.UNAUTHORIZED); + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } } diff --git a/src/main/java/net/Broken/audio/AudioM.java b/src/main/java/net/Broken/audio/AudioM.java index 49fc2fb..88d38ff 100644 --- a/src/main/java/net/Broken/audio/AudioM.java +++ b/src/main/java/net/Broken/audio/AudioM.java @@ -50,10 +50,10 @@ public class AudioM { private Guild guild; private Logger logger = LogManager.getLogger(); - private static HashMap INSTANCES = new HashMap<>(); + private static HashMap INSTANCES = new HashMap<>(); - public static AudioM getInstance(Guild guild){ - if(!INSTANCES.containsKey(guild)){ + public static AudioM getInstance(Guild guild) { + if (!INSTANCES.containsKey(guild)) { INSTANCES.put(guild, new AudioM(guild)); } @@ -61,7 +61,6 @@ public class AudioM { } - private AudioM(Guild guild) { this.playerManager = new DefaultAudioPlayerManager(); AudioSourceManagers.registerRemoteSources(playerManager); @@ -71,11 +70,12 @@ public class AudioM { /** * Load audio track from url, connect to chanel if not connected + * * @param event - * @param voiceChannel Voice channel to connect if no connected - * @param trackUrl Audio track url + * @param voiceChannel Voice channel to connect if no connected + * @param trackUrl Audio track url * @param playlistLimit Limit of playlist - * @param onHead True for adding audio track on top of playlist + * @param onHead True for adding audio track on top of playlist */ public void loadAndPlay(MessageReceivedEvent event, VoiceChannel voiceChannel, final String trackUrl, int playlistLimit, boolean onHead) { GuildMusicManager musicManager = getGuildAudioPlayer(); @@ -84,68 +84,67 @@ public class AudioM { playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() { @Override public void trackLoaded(AudioTrack track) { - logger.info("Single Track detected!"); + logger.info("[" + guild + "] Single Track detected!"); UserAudioTrack uat = new UserAudioTrack(event.getAuthor(), track); - event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Add "+track.getInfo().title+" to playlist")).queue(); + event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Add " + track.getInfo().title + " to playlist")).queue(); play(guild, voiceChannel, musicManager, uat, onHead); } @Override public void playlistLoaded(AudioPlaylist playlist) { - logger.info("Playlist detected! Limit: "+playlistLimit); + logger.info("[" + guild + "] Playlist detected! Limit: " + playlistLimit); AudioTrack firstTrack = playlist.getSelectedTrack(); - event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Add "+firstTrack.getInfo().title+" and 30 first videos to playlist !")).queue(); + event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Add " + firstTrack.getInfo().title + " and 30 first videos to playlist !")).queue(); - playListLoader(playlist, playlistLimit ,event.getAuthor() , onHead); - + playListLoader(playlist, playlistLimit, event.getAuthor(), onHead); } @Override public void noMatches() { - logger.warn("Cant find media!"); + logger.warn("[" + guild + "] Cant find media!"); event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicError("Video not found !")).queue(); } @Override public void loadFailed(FriendlyException exception) { - logger.error("Can't load media!"); + logger.error("[" + guild + "] Can't load media!"); logger.error(exception.getMessage()); event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicError("Playback error !")).queue(); } }); } - public void loadAndPlayAuto(String trackUrl){ - playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler(){ + public void loadAndPlayAuto(String trackUrl) { + playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() { @Override public void trackLoaded(AudioTrack track) { - logger.info("Auto add " + track.getInfo().title +" to playlist."); - UserAudioTrack userAudioTrack = new UserAudioTrack(MainBot.jda.getSelfUser(),track); + logger.info("[" + guild + "] Auto add " + track.getInfo().title + " to playlist."); + UserAudioTrack userAudioTrack = new UserAudioTrack(MainBot.jda.getSelfUser(), track); play(guild, playedChanel, musicManager, userAudioTrack, true); } @Override public void playlistLoaded(AudioPlaylist playlist) { AudioTrack track = playlist.getTracks().get(0); - logger.info("Auto add " + track.getInfo().title +" to playlist."); - UserAudioTrack userAudioTrack = new UserAudioTrack(MainBot.jda.getSelfUser(),track); + logger.info("[" + guild + "] Auto add " + track.getInfo().title + " to playlist."); + UserAudioTrack userAudioTrack = new UserAudioTrack(MainBot.jda.getSelfUser(), track); play(guild, playedChanel, musicManager, userAudioTrack, true); } @Override public void noMatches() { - logger.warn("Track not found: "+trackUrl); + logger.warn("[" + guild + "] Track not found: " + trackUrl); } @Override public void loadFailed(FriendlyException exception) { - logger.error("Cant load media!"); + logger.error("[" + guild + "] Cant load media!"); logger.error(exception.getMessage()); } }); @@ -154,22 +153,23 @@ public class AudioM { /** * Load playlist to playlist - * @param playlist Loaded playlist + * + * @param playlist Loaded playlist * @param playlistLimit Playlist limit - * @param user User who have submitted the playlist - * @param onHead True for adding audio track on top of playlist + * @param user User who have submitted the playlist + * @param onHead True for adding audio track on top of playlist */ - public void playListLoader(AudioPlaylist playlist, int playlistLimit, User user, boolean onHead){ + public void playListLoader(AudioPlaylist playlist, int playlistLimit, User user, boolean onHead) { int i = 0; List tracks = playlist.getTracks(); - if(onHead) + if (onHead) Collections.reverse(tracks); - - for(AudioTrack track : playlist.getTracks()){ + + for (AudioTrack track : playlist.getTracks()) { UserAudioTrack uat = new UserAudioTrack(user, track); play(guild, playedChanel, musicManager, uat, onHead); i++; - if((i>=playlistLimit && i!=-1) || i>listExtremLimit) + if ((i >= playlistLimit && i != -1) || i > listExtremLimit) break; } } @@ -187,16 +187,17 @@ public class AudioM { /** * Add single track to playlist, auto-connect if not connected to vocal chanel - * @param guild guild - * @param channel Chanel for auto-connect + * + * @param guild guild + * @param channel Chanel for auto-connect * @param musicManager Guild music manager - * @param track Track to add to playlist - * @param onHead True for adding audio track on top of playlist + * @param track Track to add to playlist + * @param onHead True for adding audio track on top of playlist */ - public void play(Guild guild, VoiceChannel channel, GuildMusicManager musicManager, UserAudioTrack track,boolean onHead) { - if(!guild.getAudioManager().isConnected()) + public void play(Guild guild, VoiceChannel channel, GuildMusicManager musicManager, UserAudioTrack track, boolean onHead) { + if (!guild.getAudioManager().isConnected()) guild.getAudioManager().openAudioConnection(channel); - if(!onHead) + if (!onHead) musicManager.scheduler.queue(track); else musicManager.scheduler.addNext(track); @@ -204,6 +205,7 @@ public class AudioM { /** * Skip current track + * * @param event */ public void skipTrack(MessageReceivedEvent event) { @@ -214,6 +216,7 @@ public class AudioM { /** * Pause current track + * * @param event */ public void pause(MessageReceivedEvent event) { @@ -227,9 +230,10 @@ public class AudioM { /** * Resume paused track + * * @param event */ - public void resume (MessageReceivedEvent event) { + public void resume(MessageReceivedEvent event) { GuildMusicManager musicManager = getGuildAudioPlayer(); musicManager.scheduler.resume(); @@ -238,6 +242,7 @@ public class AudioM { /** * Print current played track info + * * @param event */ public void info(MessageReceivedEvent event) { @@ -248,7 +253,7 @@ public class AudioM { event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk(info.title + "\n" + info.uri + "\nSubmitted by: " + userAudioTrack.getSubmittedUser().getName())).queue(); } - public void flush(MessageReceivedEvent event){ + public void flush(MessageReceivedEvent event) { GuildMusicManager musicManager = getGuildAudioPlayer(); musicManager.scheduler.flush(); event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Flush playlist!")).queue(); @@ -256,48 +261,47 @@ public class AudioM { /** * Print current playlist content + * * @param event */ - public void list(MessageReceivedEvent event){ + public void list(MessageReceivedEvent event) { GuildMusicManager musicManager = getGuildAudioPlayer(); List list = musicManager.scheduler.getList(); StringBuilder resp = new StringBuilder(); - if(list.size() == 0){ + if (list.size() == 0) { resp.append("Oh my god!\nThe playlist is empty ! \n:astonished: "); - } - else - { - for(UserAudioTrackData trackInfo : list){ + } else { + for (UserAudioTrackData trackInfo : list) { resp.append("- "); resp.append(trackInfo.getAudioTrackInfo().title); resp.append("\n"); } } - event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Playlist:\n\n"+resp.toString())).queue(); + event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Playlist:\n\n" + resp.toString())).queue(); } /** * Called by //add, only if already connected + * * @param event - * @param url Audio track url + * @param url Audio track url * @param playListLimit Limit of playlist - * @param onHead True for adding audio track on top of playlist + * @param onHead True for adding audio track on top of playlist */ public void add(MessageReceivedEvent event, String url, int playListLimit, boolean onHead) { - if(playedChanel != null){ - loadAndPlay(event ,playedChanel, url, playListLimit,onHead); - } - else - { + if (playedChanel != null) { + loadAndPlay(event, playedChanel, url, playListLimit, onHead); + } else { event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicError("Not connected to vocal chanel !")).queue(); } } /** * Stop current playing track and flush playlist + * * @param event */ - public void stop (MessageReceivedEvent event) { + public void stop(MessageReceivedEvent event) { musicManager.scheduler.stop(); musicManager.scheduler.flush(); @@ -309,7 +313,7 @@ public class AudioM { /** * Stop current playing track and flush playlist (no confirmation message) */ - public void stop () { + public void stop() { GuildMusicManager musicManager = getGuildAudioPlayer(); musicManager.scheduler.stop(); @@ -318,8 +322,8 @@ public class AudioM { guild.getAudioManager().closeAudioConnection(); } - public GuildMusicManager getGuildMusicManager(){ - if( musicManager == null) + public GuildMusicManager getGuildMusicManager() { + if (musicManager == null) musicManager = getGuildAudioPlayer(); return musicManager; diff --git a/src/main/java/net/Broken/audio/TrackScheduler.java b/src/main/java/net/Broken/audio/TrackScheduler.java index 8ba54b9..3e7a947 100644 --- a/src/main/java/net/Broken/audio/TrackScheduler.java +++ b/src/main/java/net/Broken/audio/TrackScheduler.java @@ -8,6 +8,8 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; import net.Broken.MainBot; import net.Broken.RestApi.Data.UserAudioTrackData; +import net.Broken.audio.Youtube.RelatedIdNotFound; +import net.Broken.audio.Youtube.YoutubeSearchRework; import net.Broken.audio.Youtube.YoutubeTools; import net.dv8tion.jda.api.entities.Guild; import org.apache.logging.log4j.LogManager; @@ -52,19 +54,18 @@ public class TrackScheduler extends AudioEventAdapter { // Calling startTrack with the noInterrupt set to true will start the track only if nothing is currently playing. If // something is playing, it returns false and does nothing. In that case the player was already playing so this // track goes to the queue instead. - if(track.getSubmittedUser() != MainBot.jda.getSelfUser()){ - logger.debug("Flush history"); + if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) { + logger.debug("[" + guild + "] Flush history"); history = new ArrayList<>(); } history.add(track.getAudioTrack().getIdentifier()); if (!player.startTrack(track.getAudioTrack(), true)) { queue.offer(track); - } - else{ + } else { currentPlayingTrack = track; } - if(track.getSubmittedUser() != MainBot.jda.getSelfUser()) { + if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) { needAutoPlay(); } @@ -73,13 +74,14 @@ public class TrackScheduler extends AudioEventAdapter { /** * Add track on top of playlist + * * @param track */ public void addNext(UserAudioTrack track) { // Calling startTrack with the noInterrupt set to true will start the track only if nothing is currently playing. If // something is playing, it returns false and does nothing. In that case the player was already playing so this // track goes to the queue instead. - if(track.getSubmittedUser() != MainBot.jda.getSelfUser()){ + if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) { logger.debug("Flush history"); history = new ArrayList<>(); } @@ -87,16 +89,14 @@ public class TrackScheduler extends AudioEventAdapter { history.add(track.getAudioTrack().getIdentifier()); if (!player.startTrack(track.getAudioTrack(), true)) { queue.addFirst(track); - } - else{ + } else { currentPlayingTrack = track; } - if(track.getSubmittedUser() != MainBot.jda.getSelfUser()) { + if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) { needAutoPlay(); - } - else - logger.debug("Bot add, ignore autoFlow"); + } else + logger.debug("[" + guild + "] Bot add, ignore autoFlow"); } public void pause() { @@ -108,29 +108,29 @@ public class TrackScheduler extends AudioEventAdapter { } - public void stop(){ + public void stop() { player.stopTrack(); this.currentPlayingTrack = null; player.destroy(); } - public void flush(){ + public void flush() { queue.clear(); } - public List getList(){ + public List getList() { // AudioTrack[] test = (AudioTrack[]) queue.toArray(); List temp = new ArrayList<>(); Object[] test = queue.toArray(); - for(Object track: test){ + for (Object track : test) { UserAudioTrack casted = (UserAudioTrack) track; temp.add(new UserAudioTrackData(casted.getSubmittedUser().getName(), casted.getAudioTrack().getInfo())); } return temp; } - public AudioTrackInfo getInfo(){ + public AudioTrackInfo getInfo() { return player.getPlayingTrack().getInfo(); } @@ -138,20 +138,20 @@ public class TrackScheduler extends AudioEventAdapter { return currentPlayingTrack; } - public boolean remove(String uri){ - for(UserAudioTrack track : queue){ - if(track.getAudioTrack().getInfo().uri.equals(uri)){ - if(!queue.remove(track)) { - logger.error("Delete failure!"); + public boolean remove(String uri) { + for (UserAudioTrack track : queue) { + if (track.getAudioTrack().getInfo().uri.equals(uri)) { + if (!queue.remove(track)) { + logger.error("[" + guild + "] Delete failure!"); return false; } else { - logger.info("Delete succeful"); + logger.info("[" + guild + "] Delete successful"); needAutoPlay(); return true; } } } - logger.info("Delete failure! Not found."); + logger.info("[" + guild + "] Delete failure! Not found."); return false; } @@ -163,9 +163,9 @@ public class TrackScheduler extends AudioEventAdapter { // Start the next track, regardless of if something is already playing or not. In case queue was empty, we are // giving null to startTrack, which is a valid argument and will simply stop the player. UserAudioTrack track = queue.poll(); - if(track != null) + if (track != null) this.currentPlayingTrack = track; - if(track != null) + if (track != null) player.startTrack(track.getAudioTrack(), false); needAutoPlay(); } @@ -174,27 +174,34 @@ public class TrackScheduler extends AudioEventAdapter { public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { // Only start the next track if the end reason is suitable for it (FINISHED or LOAD_FAILED) if (endReason.mayStartNext) { - logger.debug("End of track, start next."); + logger.debug("[" + guild + "] End of track, start next."); nextTrack(); } } - private void needAutoPlay(){ - if((queue.size() < 1) && autoFlow && currentPlayingTrack != null){ - logger.debug("Auto add needed!"); + private void needAutoPlay() { + if ((queue.size() < 1) && autoFlow && currentPlayingTrack != null) { + logger.debug("[" + guild.getName() + "] Auto add needed!"); AudioM audioM = AudioM.getInstance(guild); - YoutubeTools youtubeTools = YoutubeTools.getInstance(); + YoutubeSearchRework youtubeSearchRework = YoutubeSearchRework.getInstance(); try { - String id = youtubeTools.getRelatedVideo(currentPlayingTrack.getAudioTrack().getInfo().identifier, history); - logger.debug("Related id: "+id); + String id = youtubeSearchRework.getRelatedVideo(currentPlayingTrack.getAudioTrack().getInfo().identifier); + logger.debug("[" + guild.getName() + "] Related id: " + id); audioM.loadAndPlayAuto(id); + } catch (IOException | RelatedIdNotFound ex) { + logger.debug("[" + guild.getName() + "] Can't find related id, try API..."); + YoutubeTools youtubeTools = YoutubeTools.getInstance(); + try { + String id = youtubeTools.getRelatedVideo(currentPlayingTrack.getAudioTrack().getInfo().identifier, history); + logger.debug("[" + guild.getName() + "] Related id: " + id); + audioM.loadAndPlayAuto(id); - } catch (GoogleJsonResponseException e) { - logger.error("There was a service error: " + e.getDetails().getCode() + " : " + e.getDetails().getMessage()); - } catch (IOException t) { - logger.catching(t); + } catch (GoogleJsonResponseException e) { + logger.error("[" + guild.getName() + "] There was a service error: " + e.getDetails().getCode() + " : " + e.getDetails().getMessage()); + } catch (IOException t) { + logger.catching(t); + } } - } } diff --git a/src/main/java/net/Broken/audio/Youtube/RelatedIdNotFound.java b/src/main/java/net/Broken/audio/Youtube/RelatedIdNotFound.java new file mode 100644 index 0000000..90f078c --- /dev/null +++ b/src/main/java/net/Broken/audio/Youtube/RelatedIdNotFound.java @@ -0,0 +1,4 @@ +package net.Broken.audio.Youtube; + +public class RelatedIdNotFound extends Exception { +} diff --git a/src/main/java/net/Broken/audio/Youtube/YoutubeSearchRework.java b/src/main/java/net/Broken/audio/Youtube/YoutubeSearchRework.java index e2925c3..8def1df 100644 --- a/src/main/java/net/Broken/audio/Youtube/YoutubeSearchRework.java +++ b/src/main/java/net/Broken/audio/Youtube/YoutubeSearchRework.java @@ -104,4 +104,23 @@ public class YoutubeSearchRework { } return results; } + + public String getRelatedVideo(String sourceVideoId) throws IOException, RelatedIdNotFound { + sourceVideoId = URLEncoder.encode(sourceVideoId, StandardCharsets.UTF_8.toString()); + String url = "https://www.youtube.com/watch?v=" + sourceVideoId; + Document doc = getYoutubeSearchDocument(url); + + return extractRelatedVideoId(doc); + } + + private String extractRelatedVideoId(Document doc) throws RelatedIdNotFound { + Elements elements = doc.select(".autoplay-bar .content-link"); + if(elements.size() == 0){ + throw new RelatedIdNotFound(); + } + Element elem = elements.get(0); + String url = elem.attributes().get("href"); + return url.replace("/watch?v=", ""); + } + }