Encore une nouvelle api. Et aussi la séparation du travail dans des fichiers distincts.
This commit is contained in:
parent
f16ca7efb0
commit
6a3a454492
54
build.gradle
Normal file
54
build.gradle
Normal file
@ -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'
|
||||
}
|
||||
}
|
||||
10
settings.gradle
Normal file
10
settings.gradle
Normal file
@ -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"
|
||||
@ -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<AudioTrack> 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<VoiceChannel> 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<AudioTrack> it = playlist.iterator();
|
||||
int end = Integer.parseInt(soundId, 10) - 1;//Mathe way
|
||||
int i = 0;
|
||||
AudioTrack track = null;
|
||||
for(;i<end && it.hasNext();i++)
|
||||
track = it.next();
|
||||
if(i==end && track != null)
|
||||
playlist.remove(track);
|
||||
else
|
||||
notifyUser("Il n'y a pas de son dans la playlist au "+(end+1)+"ième élement", user, null);
|
||||
}else {
|
||||
Iterator<AudioTrack> 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 <T> Queue<T> appendFirst(T element,Queue<T> queue){
|
||||
Queue<T> out = new LinkedList<T>();
|
||||
out.add(element);
|
||||
for (T t : queue) {
|
||||
out.add(t);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
249
src/main/java/com/bernard/julsoundbox/GuildSoundManager.java
Normal file
249
src/main/java/com/bernard/julsoundbox/GuildSoundManager.java
Normal file
@ -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<AudioTrack> 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<AudioTrack> 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<AudioTrack> 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 <T> Queue<T> appendFirst(T element,Queue<T> queue){
|
||||
Queue<T> out = new LinkedList<T>();
|
||||
out.add(element);
|
||||
for (T t : queue)
|
||||
out.add(t);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
225
src/main/java/com/bernard/julsoundbox/JulSoundBox.java
Normal file
225
src/main/java/com/bernard/julsoundbox/JulSoundBox.java
Normal file
@ -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<Long,GuildSoundManager> managers;
|
||||
|
||||
Random randomizator;
|
||||
|
||||
public JulSoundBox(JDA jda) {
|
||||
managers = new HashMap<Long, GuildSoundManager>();
|
||||
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<VoiceChannel> 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<String> 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<String> 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<String> 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<String> 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 <T> Queue<T> appendFirst(T element,Queue<T> queue){
|
||||
Queue<T> out = new LinkedList<T>();
|
||||
out.add(element);
|
||||
for (T t : queue) {
|
||||
out.add(t);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user