diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..8c3817d --- /dev/null +++ b/build.gradle @@ -0,0 +1,54 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Java Library project to get you started. + * For more details take a look at the Java Libraries chapter in the Gradle + * user guide available at https://docs.gradle.org/4.8.1/userguide/java_library_plugin.html + */ + +plugins { + // Apply the java-library plugin to add support for Java Library + id 'java-library' +} + +task copyDependencies(type: Copy) { + group 'build' + from configurations.compile + into 'dependencies' +} + + +dependencies { + // This dependency is exported to consumers, that is to say found on their compile classpath. + api 'org.apache.commons:commons-math3:3.6.1' + + // This dependency is used internally, and not exposed to consumers on their own compile classpath. + implementation 'com.google.guava:guava:23.0' + + // Use JUnit test framework + testImplementation 'junit:junit:4.12' + + compile 'net.dv8tion:JDA:3.8.1_439' + + compile 'com.thedeanda:lorem:2.1' + + // https://mvnrepository.com/artifact/mysql/mysql-connector-java + compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.15' + + compile 'com.sedmelluq:lavaplayer:1.3.16' + + compile (name:'JuliabotAPI', ext:'jar') + compile (name:'JulData', ext:'jar') + +} + +// In this section you declare where to find the dependencies of your project +repositories { + // Use jcenter for resolving your dependencies. + // You can declare any Maven/Ivy/file repository here. + jcenter() + + flatDir { + dirs 'libs' + } +} diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..776993d --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user guide at https://docs.gradle.org/4.8.1/userguide/multi_project_builds.html + */ + +rootProject.name = "Jul'Soundbox" diff --git a/src/com/bernard/julsoundbox/JulSoundBox.java b/src/com/bernard/julsoundbox/JulSoundBox.java deleted file mode 100644 index 53d740f..0000000 --- a/src/com/bernard/julsoundbox/JulSoundBox.java +++ /dev/null @@ -1,430 +0,0 @@ -package com.bernard.julsoundbox; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.nio.ByteBuffer; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import java.util.Random; -import java.util.Scanner; - -import com.bernard.juliabot.api.Command; -import com.bernard.juliabot.api.JuLIAddon; -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.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEvent; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener; -import com.sedmelluq.discord.lavaplayer.player.event.TrackEndEvent; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers; -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.playback.AudioFrame; - -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.MessageBuilder; -import net.dv8tion.jda.api.audio.AudioSendHandler; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.GuildVoiceState; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.MessageChannel; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.entities.VoiceChannel; -import net.dv8tion.jda.api.managers.AudioManager; - -@JuLIAddon(name = "julsoundbox",devs = "Mysaa", version = "20w33a") -public class JulSoundBox { - - private static final String soundFolder = "/var/julia/julsoundbox/sounds/"; - public static final String soundExtension = ".opus"; - static AudioPlayerManager playerManager = new DefaultAudioPlayerManager(); - static AudioManager manager; - static VoiceChannel currentChannel = null; - static VoiceChannel oldChannel = null;//Si set, JuL'IA retournera dans ce salon dès qu'une chanson finira - static BernardSoundHandler soundHandler; - static Queue playlist; - Random randomizator; - static boolean play; - - @Command(name = "playing", admin = false, description = "Demande à JuL'IA quel son elle est en train de jouer") - public void playing(Guild guild, Message message) { - if(soundHandler.currentTrack == null && playlist.isEmpty()) { - notifyUser("Ben je suis en fait en train de jouer .... rien du tout", message.getAuthor(), message.getChannel()); - return; - } - EmbedBuilder builder = new EmbedBuilder(); - String playing = ""; - if(soundHandler.currentTrack == null) - playing = "Rien du tout !"; - else - playing = soundHandler.currentTrack.getIdentifier(); - builder.addField("Je joue ", playing, false); - - String queued = ""; - if(playlist.isEmpty()) - queued = "Rien du tout !"; - else { - for (AudioTrack audioTrack : playlist) - queued += audioTrack.getIdentifier().substring(soundFolder.length()) + ","; - queued = queued.substring(0, queued.length()-1); - } - builder.addField("J'ai prévu ", queued, false); - message.getChannel().sendMessage(builder.build()).complete(); - } - - public static void sneakPlay(String sound,VoiceChannel chan) { - oldChannel = currentChannel; - manager.openAudioConnection(chan); - currentChannel = chan; - - playerManager.loadItem("/var/julia/julsoundbox/sounds/" + sound + soundExtension, new AudioLoadResultHandler() { - @Override - public void trackLoaded(AudioTrack track) { - playlist = appendFirst(track, playlist); - play = true; - soundHandler.next(); - } - - @Override - public void playlistLoaded(AudioPlaylist playlist) { - System.err.println("Quoikesquevousavezfaitlà ?!"); - } - - @Override - public void noMatches() { - System.err.println("A moins de transformer le texte en données sonores brutes, je sais pas quoi prononcer"); - } - - @Override - public void loadFailed(FriendlyException exception) { - System.err.println("Je n'ai pas réussi à charger le son ... désolé (en meme temps, vu comme mes devs codent !)"); - } - }); - - } - - @Command(name = "come", admin = true, description = "Ammène julia dans le salon vocal auquel l'utilisateur est connécté") - public void come(Guild guild, Message message, User user) { - final GuildVoiceState memberVoiceState = guild.getMember(user).getVoiceState(); - System.out.println("Coming into channel of voice state "+memberVoiceState); - if(!memberVoiceState.inVoiceChannel()) - manager.closeAudioConnection(); - else { - manager.openAudioConnection(memberVoiceState.getChannel()); - currentChannel = memberVoiceState.getChannel(); - } - } - - @Command(name = "go", admin = true, description = "Ammène julia dans le salon spécifié") - public void go(Guild guild, Message message, User user) { - String channelName = message.getContentRaw().substring(message.getContentRaw().indexOf("go")+3); - System.out.println("Going to channel : "+channelName); - switch(channelName) { - case "néant": - case "rien": - case "away": - case "null": - case "nichts": - if(currentChannel != null) - manager.closeAudioConnection(); - currentChannel = null; - return; - } - List chans = guild.getVoiceChannelsByName(channelName,true); - if(chans.size() <= 0) { - notifyUser("Je ne connais pas le channel '"+channelName+"'", user, message.getChannel()); - return; - } - currentChannel = chans.get(0); - manager.openAudioConnection(currentChannel); - } - - @Command(name = "play", admin = true, description = "Reprends ou lance la lecture d'un son") - public void play(Guild guild, Message message, User user) { - String soundName = null; - if(message.getContentRaw().endsWith("play")) { - if(soundHandler.currentTrack != null || !playlist.isEmpty()) { - soundHandler.update(true); - return; - }else { - System.out.println("Random mode !!!"); - File[] songsFiles = new File("/var/julia/julsoundbox/sounds/").listFiles(); - soundName = songsFiles[randomizator.nextInt(songsFiles.length)].getName().substring(0, soundExtension.length()+1); - } - }else{ - soundName = message.getContentRaw().substring(message.getContentRaw().indexOf("play")+5); - if(!checkUserSoundPermission(user, soundName)){ - notifyUser("Vous n'avez pas accès à ce morceau", user, null); - return; - } - } - System.out.println("Trying to play : "+soundName); - playerManager.loadItem("/var/julia/julsoundbox/sounds/" + soundName + soundExtension, new AudioLoadResultHandler() { - @Override - public void trackLoaded(AudioTrack track) { - playlist = appendFirst(track, playlist); - play = true; - soundHandler.next(); - } - - @Override - public void playlistLoaded(AudioPlaylist playlist) { - notifyUser("Quoikesquevousavezfaitlà ?!", user, null); - } - - @Override - public void noMatches() { - notifyUser("A moins de transformer le texte en données sonores brutes, je sais pas quoi prononcer", user, null); - } - - @Override - public void loadFailed(FriendlyException exception) { - notifyUser("Je n'ai pas réussi à charger le son ... désolé (en meme temps, vu comme mes devs codent !)", user, null); - } - }); - } - - @Command(name = "play2", admin = true, description = "Reprends ou lance la lecture d'un son2") - public void play2(Guild guild, Message message, User user) { - String soundName = message.getContentRaw().substring(message.getContentRaw().indexOf("play2")+6); - System.out.println("Trying to play : "+soundName); - playerManager.loadItem("/var/julia/julsoundbox/sounds/" + soundName + soundExtension, new AudioLoadResultHandler() { - @Override - public void trackLoaded(AudioTrack track) { - soundHandler.altTrack = track; - soundHandler.altPlayer.startTrack(track, false); - } - - @Override - public void playlistLoaded(AudioPlaylist playlist) { - notifyUser("Quoikesquevousavezfaitlà ?!", user, null); - } - - @Override - public void noMatches() { - notifyUser("A moins de transformer le texte en données sonores brutes, je sais pas quoi prononcer", user, null); - } - - @Override - public void loadFailed(FriendlyException exception) { - notifyUser("Je n'ai pas réussi à charger le son ... désolé (en meme temps, vu comme mes devs codent !)", user, null); - } - }); - } - - @Command(name = "queue", admin = true, description = "Ajoute un son à la liste de lecture") - public void queue(Guild guild, Message message, User user) { - String soundName = null; - if(message.getContentRaw().indexOf("queue")+5 == message.getContentRaw().length()) { - File[] songsFiles = new File("/var/julia/julsoundbox/sounds/").listFiles(); - soundName = songsFiles[randomizator.nextInt(songsFiles.length)].getName().substring(0, ".opus".length()); - }else{ - soundName = message.getContentRaw().substring(message.getContentRaw().indexOf("queue")+6); - if(!checkUserSoundPermission(user, soundName)){ - notifyUser("Vous n'avez pas accès à ce morceau", user, null); - return; - } - } - playerManager.loadItem(soundFolder + soundName + ".opus", new AudioLoadResultHandler() { - @Override - public void trackLoaded(AudioTrack track) { - playlist.add(track); - soundHandler.update(); - } - - @Override - public void playlistLoaded(AudioPlaylist playlist) { - notifyUser("Quoikesquevousavezfaitlà ?!", user, null); - } - - @Override - public void noMatches() { - notifyUser("A moins de transformer le texte en données sonores brutes, je sais pas quoi prononcer", user, null); - } - - @Override - public void loadFailed(FriendlyException exception) { - notifyUser("Je n'ai pas réussi à charger le son ... désolé (en meme temps, vu comme mes devs codent !)", user, null); - } - }); - } - - @Command(name = "unqueue", admin = true, description = "Enlève un son de la liste de lecture")//TODO test - public void unqueue(Guild guild, Message message, User user) { - String soundId = message.getContentRaw().substring(message.getContentRaw().indexOf("unqueue")+8); - if(soundId.matches("^[0-9]+$")) { - Iterator it = playlist.iterator(); - int end = Integer.parseInt(soundId, 10) - 1;//Mathe way - int i = 0; - AudioTrack track = null; - for(;i it = playlist.iterator(); - while(it.hasNext()) { - AudioTrack t = it.next(); - if(t.getUserData().equals(soundId)) - playlist.remove(t); - } - } - soundHandler.update(); - } - - @Command(name = "pause", admin = true, description = "Met le son joué en pause (wow)") - public void pause(Guild guild, Message message, User user) { - soundHandler.update(false); - } - - @Command(name = "chut", admin = true, description = "Arette le son que JuL'IA joue (un !!play reprendra le morceau suivant ") - public void chut(Guild guild, Message message, User user) { - play = false; - soundHandler.next(); - } - - @Command(name = "soundInit", admin = true, description = "Evite que tout le programme ne crashe .... a ne pas oublier (en attendant que tout 'fonctionne' ...)") - public void soundInit(Guild guild) { - playerManager = new DefaultAudioPlayerManager(); - soundHandler = new BernardSoundHandler(); - manager = guild.getAudioManager(); - AudioSourceManagers.registerLocalSource(playerManager); - manager.setSendingHandler(soundHandler); - currentChannel = null; - playlist = new LinkedList<>(); - randomizator = new Random(); - play = false; - } - - public class BernardSoundHandler implements AudioSendHandler,AudioEventListener { - - public AudioTrack currentTrack; - public AudioTrack altTrack; - - private final AudioPlayer audioPlayer; - final AudioPlayer altPlayer; - - public BernardSoundHandler() { - audioPlayer = playerManager.createPlayer(); - altPlayer = playerManager.createPlayer(); - audioPlayer.addListener(this); - altPlayer.addListener(this); - } - - public void next() { - currentTrack = playlist.poll(); - audioPlayer.startTrack(currentTrack, false); - update(); - } - - public void update() { - audioPlayer.setPaused(!JulSoundBox.play); - } - - public void update(boolean play) { - JulSoundBox.play = play; - update(); - } - - @Override - public void onEvent(AudioEvent event) { - if(event instanceof TrackEndEvent) { - altTrack = null; - if(oldChannel != null) { - manager.openAudioConnection(oldChannel); - currentChannel = oldChannel; - - } - if(playlist.size() > 0) { - currentTrack = playlist.poll(); - audioPlayer.startTrack(currentTrack, false); - update(); - }else { - play = false; - currentTrack = null; - } - - } - } - - - private AudioFrame lastFrame; - /////////// Methods for sound playing /////////// - @Override - public boolean canProvide() { - if(altTrack != null) { - AudioFrame f1 = audioPlayer.provide(); - AudioFrame f2 = altPlayer.provide(); - lastFrame = (Math.random() > 0.5)?f1:f2; - }else - lastFrame = audioPlayer.provide(); - return lastFrame != null; - } - - @Override - public ByteBuffer provide20MsAudio() { - return ByteBuffer.wrap(lastFrame.data); - } - - @Override - public boolean isOpus() { - return true; - } - - } - - public static final boolean checkUserSoundPermission(User user,String sound) { - if(sound.indexOf("/") == -1) - return true; - File soundFile = new File(soundFolder,sound+".opus"); - if(!soundFile.exists()) - return true;//will be catched later, returning false will cause the 'not permitted' message appear - File lockFile = new File(soundFile.getParent(),"lock");//TODO Change with BernardFilesAPI - if(!lockFile.exists()) - return true;//No lock file : the folder is open - try { - Scanner sc = new Scanner(new FileInputStream(lockFile)); - while(sc.hasNextLine()) - if(user.getId().equals(sc.nextLine())) { - sc.close(); - return true; - } - sc.close(); - } catch (FileNotFoundException e) { - System.err.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); - System.err.println("No right to access to "+lockFile.getAbsolutePath()); - e.printStackTrace(); - System.err.println("\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/"); - } - return false; - } - - //////////// Useful static functions /////////////// - - public static final void notifyUser(String problem, User user, MessageChannel channel) { - MessageBuilder builder = new MessageBuilder(); - builder.append(user); - builder.append(" : "); - builder.append(problem); - user.openPrivateChannel().queue((chan) -> { - chan.sendMessage(builder.build()).queue(); - }); - } - - public static final Queue appendFirst(T element,Queue queue){ - Queue out = new LinkedList(); - out.add(element); - for (T t : queue) { - out.add(t); - } - return out; - } - -} diff --git a/src/main/java/com/bernard/julsoundbox/GuildSoundManager.java b/src/main/java/com/bernard/julsoundbox/GuildSoundManager.java new file mode 100644 index 0000000..c3189b1 --- /dev/null +++ b/src/main/java/com/bernard/julsoundbox/GuildSoundManager.java @@ -0,0 +1,249 @@ +package com.bernard.julsoundbox; + +import java.util.LinkedList; +import java.util.Queue; + +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.player.DefaultAudioPlayerManager; +import com.sedmelluq.discord.lavaplayer.player.event.AudioEvent; +import com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener; +import com.sedmelluq.discord.lavaplayer.player.event.TrackEndEvent; +import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers; +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.playback.AudioFrame; + +import net.dv8tion.jda.core.EmbedBuilder; +import net.dv8tion.jda.core.audio.AudioSendHandler; +import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.MessageEmbed; +import net.dv8tion.jda.core.entities.VoiceChannel; +import net.dv8tion.jda.core.managers.AudioManager; + +public class GuildSoundManager { + + AudioPlayerManager playerManager; + AudioManager manager; + VoiceChannel currentChannel = null; + BernardSoundHandler soundHandler; + Queue playlist; + boolean play; + + + public GuildSoundManager(Guild guild) { + + playerManager = new DefaultAudioPlayerManager(); + soundHandler = new BernardSoundHandler(); + manager = guild.getAudioManager(); + AudioSourceManagers.registerLocalSource(playerManager); + manager.setSendingHandler(soundHandler); + currentChannel = null; + playlist = new LinkedList<>(); + play = false; + + } + + public MessageEmbed playing() { + if(soundHandler.currentTrack == null && playlist.isEmpty()) { + EmbedBuilder mb = new EmbedBuilder(); + mb.setTitle("Ben je suis en fait en train de jouer .... rien du tout"); + return mb.build(); + } + EmbedBuilder builder = new EmbedBuilder(); + String playing = ""; + if(soundHandler.currentTrack == null) + playing = "Rien du tout !"; + else + playing = soundHandler.currentTrack.getIdentifier(); + builder.addField("Je joue ", playing, false); + + String queued = ""; + if(playlist.isEmpty()) + queued = "Rien du tout !"; + else { + for (AudioTrack audioTrack : playlist) + queued += audioTrack.getUserData() + "\n"; + queued = queued.substring(0, queued.length()-1); + } + builder.addField("J'ai prévu ", queued, false); + return builder.build(); + } + + + public void go(VoiceChannel chan) { + if(chan == null) { + System.out.println("Je quite les salons vocaux"); + manager.closeAudioConnection(); + }else { + System.out.println("Coming into channel "+chan==null?"néant":chan.getName()); + manager.openAudioConnection(chan); + currentChannel = chan; + } + } + + public void play(String path,String song) { + System.out.println("Trying to play : "+path); + playerManager.loadItem(path, new AudioLoadResultHandler() { + @Override + public void trackLoaded(AudioTrack track) { + track.setUserData(song); + playlist = appendFirst(track, playlist); + soundHandler.update(); + } + + @Override + public void playlistLoaded(AudioPlaylist playlist) { + System.err.println("Quoikesquevousavezfaitlà ?! Vous avez juste essayé de lancer "+path); + } + + @Override + public void noMatches() { + System.err.println("A moins de transformer le texte en données sonores brutes, je sais pas quoi prononcer "+path); + } + + @Override + public void loadFailed(FriendlyException exception) { + System.err.println("Je n'ai pas réussi à charger le son ... désolé (en meme temps, vu comme mes devs codent !) "+exception.getMessage()); + } + }); + } + + + public void queue(String path,String song) { + + playerManager.loadItem(path, new AudioLoadResultHandler() { + @Override + public void trackLoaded(AudioTrack track) { + track.setUserData(song); + playlist.add(track); + soundHandler.update(); + } + + @Override + public void playlistLoaded(AudioPlaylist playlist) { + System.err.println("Quoikesquevousavezfaitlà ?! Vous avez juste essayé de lancer "+path); + } + + @Override + public void noMatches() { + System.err.println("A moins de transformer le texte en données sonores brutes, je sais pas quoi prononcer "+path); + } + + @Override + public void loadFailed(FriendlyException exception) { + System.err.println("Je n'ai pas réussi à charger le son ... désolé (en meme temps, vu comme mes devs codent !) "+exception.getMessage()); + } + }); + } + + public void unqueue(int pos) { + Queue out = new LinkedList<>(); + for (int i = 0; i < playlist.size(); i++) + if(i!=pos)out.add(playlist.poll()); + else playlist.poll(); + playlist = out; + soundHandler.update(); + } + + public void unqueue(String song) { + Queue out = new LinkedList<>(); + for (int i = 0; i < playlist.size(); i++) + if(playlist.peek().getUserData().equals(song))out.add(playlist.poll()); + else playlist.poll(); + playlist = out; + soundHandler.update(); + } + + public void setPlay(boolean play) { + soundHandler.update(play); + } + + public void update() { + soundHandler.update(); + } + + public void next() { + soundHandler.next(); + } + + public boolean isQueueEmpty() { + return playlist.isEmpty(); + } + + public class BernardSoundHandler implements AudioSendHandler,AudioEventListener { + + public AudioTrack currentTrack; + + private final AudioPlayer audioPlayer; + + public BernardSoundHandler() { + audioPlayer = playerManager.createPlayer(); + audioPlayer.addListener(this); + } + + public void next() { + currentTrack = playlist.poll(); + audioPlayer.startTrack(currentTrack, false); + update(); + } + + public void update() { + checkNext(); + audioPlayer.setPaused(!play); + } + + public void update(boolean play) { + GuildSoundManager.this.play = play; + update(); + } + + @Override + public void onEvent(AudioEvent event) { + if(event instanceof TrackEndEvent) { + currentTrack = null; + checkNext(); + } + } + public void checkNext() { + if(playlist.size() > 0 && currentTrack == null) { + currentTrack = playlist.poll(); + audioPlayer.startTrack(currentTrack, false); + update(); + } else { + play = false; + } + } + + private AudioFrame lastFrame; + /////////// Methods for sound playing /////////// + @Override + public boolean canProvide() { + lastFrame = audioPlayer.provide(); + return lastFrame != null; + } + + @Override + public byte[] provide20MsAudio() { + return lastFrame.getData(); + } + + @Override + public boolean isOpus() { + return true; + } + + } + + public static final Queue appendFirst(T element,Queue queue){ + Queue out = new LinkedList(); + out.add(element); + for (T t : queue) + out.add(t); + return out; + } + + +} diff --git a/src/main/java/com/bernard/julsoundbox/JulSoundBox.java b/src/main/java/com/bernard/julsoundbox/JulSoundBox.java new file mode 100644 index 0000000..06061ee --- /dev/null +++ b/src/main/java/com/bernard/julsoundbox/JulSoundBox.java @@ -0,0 +1,225 @@ +package com.bernard.julsoundbox; + +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Random; + +import com.bernard.juldata.JuLData; +import com.bernard.juliabot.api.Command; +import com.bernard.juliabot.api.DiscordCCommande; +import com.bernard.juliabot.api.JuLIAddon; + +import net.dv8tion.jda.core.JDA; +import net.dv8tion.jda.core.MessageBuilder; +import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.GuildVoiceState; +import net.dv8tion.jda.core.entities.MessageChannel; +import net.dv8tion.jda.core.entities.MessageEmbed; +import net.dv8tion.jda.core.entities.User; +import net.dv8tion.jda.core.entities.VoiceChannel; + +@JuLIAddon(name="julsoundbox", devs = "Bernard", version="beta", important=true) +public class JulSoundBox { + + Map managers; + + Random randomizator; + + public JulSoundBox(JDA jda) { + managers = new HashMap(); + randomizator = new Random(); + } + + public GuildSoundManager getOrInitGS(DiscordCCommande ccommande) { + Guild g = ccommande.getMessage().getGuild(); + if(g==null) { + notifyUser("Veuilez envoyer ce message dans un serveur pour que je puisse vois dire ce que je joues dans cette liste en question", ccommande); + return null; + } + if(!managers.containsKey(g.getIdLong())) + managers.put(g.getIdLong(), new GuildSoundManager(g)); + return managers.get(g.getIdLong()); + } + + @Command(name = "playing",aliases = "kestujoues", admin = false, description = "Demande à JuL'IA quel son elle est en train de jouer") + public void playing(DiscordCCommande ccommande) { + GuildSoundManager gs = getOrInitGS(ccommande); + if(gs == null)return; + MessageEmbed toSend = gs.playing(); + System.out.println(toSend.toString()); + ccommande.getChannel().sendMessage(toSend).queue(); + } + + + + @Command(name = "come", admin = true, description = "Ammène julia dans le salon vocal auquel l'utilisateur est connecté") + public void come(DiscordCCommande ccommande) { + GuildSoundManager gs = getOrInitGS(ccommande); + if(gs == null)return; + final GuildVoiceState memberVoiceState = ccommande.getMessage().getGuild().getMember(ccommande.getUser()).getVoiceState(); + if(!memberVoiceState.inVoiceChannel()) + gs.go(null); + else + gs.go(memberVoiceState.getChannel()); + } + + @Command(name = "go", admin = true, description = "Ammène julia dans le salon spécifié") + public void go(DiscordCCommande ccommande) { + GuildSoundManager gs = getOrInitGS(ccommande); + if(gs == null)return; + + switch(ccommande.getArguments().getNomme(1)) { + case "néant": + case "rien": + case "away": + case "null": + case "nichts": + gs.go(null); + return; + } + String channelName = ccommande.getStringCommand().substring(ccommande.getArguments().getNomme(0).length()); + List chans = ccommande.getMessage().getGuild().getVoiceChannelsByName(channelName,true); + if(chans.size() <= 0) { + ccommande.getChannel().sendMessage("Je ne connais pas le channel '"+channelName+"'"); + return; + } + gs.go(chans.get(0)); + } + + + @Command(name = "play", admin = true, description = "Reprends ou lance la lecture d'un son") + public void play(DiscordCCommande ccommande) { + GuildSoundManager gs = getOrInitGS(ccommande); + if(gs == null)return; + JuLData jd = JuLData.get("julsoundbox", ccommande.getUser()); + if(ccommande.getArguments().getNommeCount() > 0) { + List toPlay = ccommande.getArguments().getNommes(); + toPlay.remove(0); + for (int i = 1; i < ccommande.getArguments().getNommes().size(); i++) { + String song = ccommande.getArguments().getNomme(i); + if(jd.find(song)) + try { + gs.play(jd.filename(song), ccommande.getUser().getId()+":"+song); + } catch (FileNotFoundException e) { + System.err.println("Mais ... je viens juste de check ?!"); + e.printStackTrace(); + } + else + ccommande.getChannel().sendMessage("Je ne connais pas ce truc là ... "+song+" ... vous m'apprenderez ?"); + } + }else if(gs.isQueueEmpty()){ + //Random mode + System.out.println("Random mode !!!"); + List songs = jd.listPublic("/"); + String toPlay = songs.get(randomizator.nextInt(songs.size())); + try { + gs.play(jd.filenamePublic(toPlay), ccommande.getUser().getId()+":"+toPlay); + } catch (FileNotFoundException e) { + System.err.println("Kestufout Tu bouges les fichiers maintenant ?!"); + e.printStackTrace(); + } + } + gs.setPlay(true); + } + + + @Command(name = "queue",admin = true, description = "Ajoute un son à la liste de lecture") + public void queue(DiscordCCommande ccommande) { + GuildSoundManager gs = getOrInitGS(ccommande); + if(gs == null)return; + JuLData jd = JuLData.get("julsoundbox", ccommande.getUser()); + if(ccommande.getArguments().getNommeCount() > 0) { + List toPlay = ccommande.getArguments().getNommes(); + toPlay.remove(0); + for (int i = 1; i < ccommande.getArguments().getNommes().size(); i++) { + String song = ccommande.getArguments().getNomme(i); + if(jd.find(song)) + try { + gs.queue(jd.filename(song), ccommande.getUser().getId()+":"+song); + } catch (FileNotFoundException e) { + System.err.println("Mais ... je viens juste de check ?!"); + e.printStackTrace(); + } + else + ccommande.getChannel().sendMessage("Je ne connais pas ce truc là ... "+song+" ... vous m'apprenderez ?"); + } + }else if(gs.isQueueEmpty()){ + //Random mode + System.out.println("Random mode !!!"); + List songs = jd.listPublic("/"); + String toPlay = songs.get(randomizator.nextInt(songs.size())); + try { + gs.queue(jd.filenamePublic(toPlay), ccommande.getUser().getId()+":"+toPlay); + } catch (FileNotFoundException e) { + System.err.println("Kestufout Tu bouges les fichiers maintenant ?!"); + e.printStackTrace(); + } + } + + } + + @Command(name = "unqueue", admin = true, description = "Enlève un son de la liste de lecture")//TODO test + public void unqueue(DiscordCCommande ccommande) { + GuildSoundManager gs = getOrInitGS(ccommande); + if(gs == null)return; + if(ccommande.getArguments().getNommeCount() == 1) { + notifyUser("Il me faut un parametre en plus ...", ccommande); + return; + } + String soundId = ccommande.getArguments().getNomme(1); + if(soundId.matches("^[0-9]+$")) { + int n = Integer.parseInt(soundId, 10) - 1;//Mathe way + gs.unqueue(n); + }else { + gs.unqueue(soundId); + } + gs.update(); + } + + @Command(name = "pause", admin = true, description = "Met le son joué en pause (wow)") + public void pause(DiscordCCommande ccommande) { + GuildSoundManager gs = getOrInitGS(ccommande); + if(gs == null)return; + gs.setPlay(false); + } + + @Command(name = "chut", admin = true, description = "Arette le son que JuL'IA joue (un !!play reprendra le morceau suivant ") + public void chut(DiscordCCommande ccommande) { + GuildSoundManager gs = getOrInitGS(ccommande); + if(gs == null)return; + gs.next(); + gs.setPlay(false); + } + + + + + //////////// Useful static functions /////////////// + public static final void notifyUser(String problem, DiscordCCommande ccommande) { + notifyUser(problem, ccommande.getUser(), ccommande.getChannel()); + } + public static final void notifyUser(String problem, User user, MessageChannel channel) { + + MessageBuilder builder = new MessageBuilder(); + builder.append(user); + builder.append(" : "); + builder.append(problem); + user.openPrivateChannel().queue((chan) -> { + chan.sendMessage(builder.build()).queue(); + }); + } + + public static final Queue appendFirst(T element,Queue queue){ + Queue out = new LinkedList(); + out.add(element); + for (T t : queue) { + out.add(t); + } + return out; + } + +}