From 8ef0634fff740d10668c80a0c57a35ff5e9f635c Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Sat, 30 Jun 2018 18:01:00 -0400 Subject: Adding the ability to play an audio clip when a user joins the voice channel Not the prettiest thing in the world --- soundchan.properties.example | 3 + .../java/soundchan/BotListener/BotListener.java | 76 +++++++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/soundchan.properties.example b/soundchan.properties.example index f862cc5..6848d18 100644 --- a/soundchan.properties.example +++ b/soundchan.properties.example @@ -6,3 +6,6 @@ localFilePath=C:\\PATH\\TO\\SOUNDS\\DIRECTORY //The user for the followingUser=USERNAME + +//If you want SoundChan to play an audio file whit their name when a user joins the channel +audioOnUserJoin=on/off diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index b09fffc..8c144c6 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -11,6 +11,7 @@ import net.dv8tion.jda.client.events.call.voice.CallVoiceJoinEvent; import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.MessageChannel; import net.dv8tion.jda.core.entities.VoiceChannel; +import net.dv8tion.jda.core.events.guild.voice.GuildVoiceJoinEvent; import net.dv8tion.jda.core.events.guild.voice.GuildVoiceMoveEvent; import net.dv8tion.jda.core.events.message.MessageReceivedEvent; import net.dv8tion.jda.core.hooks.ListenerAdapter; @@ -26,13 +27,16 @@ public class BotListener extends ListenerAdapter{ private long monitoredGuildId = -1; private Guild monitoredGuild; - private static String followingUser; - private static String localFilePath; private static LocalAudioManager localManager; private final AudioPlayerManager playerManager; private final Map musicManagers; private BotListenerHelpers helper = new BotListenerHelpers(); + // From configuration file + private static String followingUser; + private static String localFilePath; + private static boolean audioOnUserJoin; + public BotListener(Properties properties) { this.musicManagers = new HashMap<>(); @@ -42,6 +46,8 @@ public class BotListener extends ListenerAdapter{ localFilePath = properties.getProperty("localFilePath"); followingUser = properties.getProperty("followingUser"); + String temp = properties.getProperty("audioOnUserJoin"); + audioOnUserJoin = settingEnableCheck(temp); localManager = new LocalAudioManager(localFilePath); } @@ -61,7 +67,59 @@ public class BotListener extends ListenerAdapter{ @Override public void onCallVoiceJoin(CallVoiceJoinEvent event){ + super.onCallVoiceJoin(event); + } + + /** + * Plays an audio clip when a user connects to the voice channel if enabled in the config file. For the sound to play, + * there needs to be a sound file with the same name as the user, otherwise it won't play anything. + * @param event + */ + @Override + public void onGuildVoiceJoin(GuildVoiceJoinEvent event) { + if(audioOnUserJoin) { + String filepath = localManager.GetFilePath(event.getMember().getEffectiveName()); + if (!filepath.contentEquals("")) { + GuildMusicManager musicManager = getGuildAudioPlayer(); + + playerManager.loadItemOrdered(musicManager, filepath, new AudioLoadResultHandler() { + @Override + public void trackLoaded(AudioTrack track) { + int timeStart = filepath.lastIndexOf('='); + if (timeStart != -1) { + String timeString = filepath.substring(timeStart); + + //The format will be 1h2m53s, need to parse that into seconds and then call + //track.setPosition(long position) + + } + + play(monitoredGuild, musicManager, track, true); + } + @Override + public void playlistLoaded(AudioPlaylist playlist) { + AudioTrack firstTrack = playlist.getSelectedTrack(); + + if (firstTrack == null) { + firstTrack = playlist.getTracks().get(0); + } + play(monitoredGuild, musicManager, firstTrack, false); + } + + @Override + public void noMatches() { + //channel.sendMessage("Nothing found by " + trackUrl).queue(); + } + + @Override + public void loadFailed(FriendlyException exception) { + //channel.sendMessage("Could not play: " + exception.getMessage()).queue(); + } + }); + } + } + super.onGuildVoiceJoin(event); } @@ -287,4 +345,18 @@ public class BotListener extends ListenerAdapter{ } } + /** + * Checks the string for some reason to enable/disable a setting. + * @param value A string (probably read in from config file) + * @return True if it matches a value to enable, False otherwise + */ + private static boolean settingEnableCheck(String value) { + if(value.contentEquals("true") || value.contentEquals("1") || + value.contentEquals("yes") || value.contentEquals("on") || + value.contentEquals("enable")) + return true; + else + return false; + } + } -- cgit v1.2.3 From 652582ea0338add8d04ba42daa8f3c0956fa071d Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Sun, 1 Jul 2018 18:24:00 -0400 Subject: Cleaning up things a bit --- src/main/java/soundchan/BotListener/BotListener.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 8c144c6..95fef3c 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -85,15 +85,6 @@ public class BotListener extends ListenerAdapter{ playerManager.loadItemOrdered(musicManager, filepath, new AudioLoadResultHandler() { @Override public void trackLoaded(AudioTrack track) { - int timeStart = filepath.lastIndexOf('='); - if (timeStart != -1) { - String timeString = filepath.substring(timeStart); - - //The format will be 1h2m53s, need to parse that into seconds and then call - //track.setPosition(long position) - - } - play(monitoredGuild, musicManager, track, true); } @@ -109,12 +100,12 @@ public class BotListener extends ListenerAdapter{ @Override public void noMatches() { - //channel.sendMessage("Nothing found by " + trackUrl).queue(); + // Needed, but shouldn't be called } @Override public void loadFailed(FriendlyException exception) { - //channel.sendMessage("Could not play: " + exception.getMessage()).queue(); + // Needed, but shouldn't be called } }); } @@ -351,6 +342,7 @@ public class BotListener extends ListenerAdapter{ * @return True if it matches a value to enable, False otherwise */ private static boolean settingEnableCheck(String value) { + value = value.toLowerCase(); if(value.contentEquals("true") || value.contentEquals("1") || value.contentEquals("yes") || value.contentEquals("on") || value.contentEquals("enable")) -- cgit v1.2.3 From 7a23679a99f692e4dc7ee2ab109f66fe96054ba2 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Sun, 1 Jul 2018 19:02:35 -0400 Subject: Adding error output --- src/main/java/soundchan/BotListener/BotListener.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 95fef3c..33b9b7a 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -101,11 +101,13 @@ public class BotListener extends ListenerAdapter{ @Override public void noMatches() { // Needed, but shouldn't be called + System.out.println("Nothing found for " + event.getMember().getEffectiveName()); } @Override public void loadFailed(FriendlyException exception) { // Needed, but shouldn't be called + System.out.println("Could not play: " + exception.getMessage()); } }); } -- cgit v1.2.3 From 6ffac3806e3369649ae26a7c9a58baaf52c35829 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Sun, 1 Jul 2018 20:32:23 -0400 Subject: Adding in user/sound relation from a file You can now have a file with all the users and the intro sound to play without having to have multiple copies of the same sound --- soundchan.properties.example | 5 +- .../java/soundchan/BotListener/BotListener.java | 6 +- src/main/java/soundchan/LocalAudioManager.java | 75 +++++++++++++++++++++- usersound.properties.example | 4 ++ 4 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 usersound.properties.example diff --git a/soundchan.properties.example b/soundchan.properties.example index 6848d18..2ba3290 100644 --- a/soundchan.properties.example +++ b/soundchan.properties.example @@ -7,5 +7,8 @@ localFilePath=C:\\PATH\\TO\\SOUNDS\\DIRECTORY //The user for the followingUser=USERNAME -//If you want SoundChan to play an audio file whit their name when a user joins the channel +//If you want SoundChan to play an audio file whit their name when a user joins the channel or have that information come from below file audioOnUserJoin=on/off + +//The file where users and sound clips are related, see usersound.properties.example for more info +userAudioFilePath=C:\\PATH\\TO\\USER\\SOUND\\FILE diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 33b9b7a..cccb39a 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -48,7 +48,11 @@ public class BotListener extends ListenerAdapter{ followingUser = properties.getProperty("followingUser"); String temp = properties.getProperty("audioOnUserJoin"); audioOnUserJoin = settingEnableCheck(temp); - localManager = new LocalAudioManager(localFilePath); + if(audioOnUserJoin) { + localManager = new LocalAudioManager(localFilePath, properties.getProperty("userAudioFilePath")); + } + else + localManager = new LocalAudioManager(localFilePath); } private synchronized GuildMusicManager getGuildAudioPlayer() { diff --git a/src/main/java/soundchan/LocalAudioManager.java b/src/main/java/soundchan/LocalAudioManager.java index 9a4e299..e645fe7 100644 --- a/src/main/java/soundchan/LocalAudioManager.java +++ b/src/main/java/soundchan/LocalAudioManager.java @@ -3,6 +3,9 @@ package soundchan; import net.dv8tion.jda.core.entities.MessageChannel; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.*; public class LocalAudioManager { @@ -12,6 +15,7 @@ public class LocalAudioManager { */ public Map filenameDict; + public Map usernameDict; private String filepath; public LocalAudioManager(String filepath_in){ @@ -20,13 +24,41 @@ public class LocalAudioManager { PopulateFiles(); } + /** + * Constructor for when there is a file listing users and sounds to play for them + * @param filepath_in Path to folder where sounds are located + * @param userSoundFile Path to file with users and sounds + */ + public LocalAudioManager(String filepath_in, String userSoundFile) { + filepath = filepath_in; + filenameDict = new HashMap<>(); + usernameDict = new HashMap<>(); + PopulateFiles(); + MapUserAudio(userSoundFile); + } + + /** + * Gives filepath to sound to play either from a command or when given a username + * @param command Command or username to play soundbite + * @return Path to sound, or "" if no sound for given command + */ public String GetFilePath(String command){ + String path; try{ - return filepath + "/" + filenameDict.get(command); + path = filepath + "/" + filenameDict.get(command); }catch(Exception ex){ System.out.println("File " + command + " not found!"); + path = ""; + } + if(path.contentEquals("") || path.contentEquals(filepath + "/null")) { + try { + path = filepath + "/" + usernameDict.get(command); + } catch (Exception ex) { + System.out.println("File " + command + " not found!"); + path = ""; + } } - return ""; + return path; } public void ListSounds(MessageChannel channel){ @@ -52,5 +84,44 @@ public class LocalAudioManager { } } + /** + * Reads in users and their respective sounds from file, then builds a map of users to the filenames. This assumes + * filenames for the sounds are valid, but doesn't check for them. + * @param userSoundFile The file (with path if required) with listing of users and the sounds to play when they join + */ + private void MapUserAudio(String userSoundFile) { + Properties userSoundProp = LoadProperties(userSoundFile); + Set users = userSoundProp.stringPropertyNames(); + for(String user : users) { + String soundFile = userSoundProp.getProperty(user); + usernameDict.put(user, soundFile); + } + + } + + /** + * Builds a property object from a file. + * @param filename File to be read + * @return Property object with information from file + */ + private static Properties LoadProperties(String filename){ + Properties properties = new Properties(); + InputStream input = null; + try{ + input = new FileInputStream(filename); + properties.load(input); + + }catch (IOException ex){ + ex.printStackTrace(); + } finally { + try { + input.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return properties; + } + } diff --git a/usersound.properties.example b/usersound.properties.example new file mode 100644 index 0000000..9575f01 --- /dev/null +++ b/usersound.properties.example @@ -0,0 +1,4 @@ +//Here we can map a user to a sound file, so many users can share the same intro soundbite and/or so you don't have to have extra copies of the same sound file + +//Discord user and the file (with extension) +Queen=WeAreTheChampions.mp3 -- cgit v1.2.3 From 296d1b7c87c5497425f6b46070f46bf4caa22ad1 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Fri, 6 Jul 2018 20:57:14 -0400 Subject: Breaking out properties loading and adding comments --- src/main/java/soundchan/BotListener/BotListener.java | 8 ++++++++ usersound.properties.example | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index cccb39a..7a65f78 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -44,6 +44,14 @@ public class BotListener extends ListenerAdapter{ AudioSourceManagers.registerRemoteSources(playerManager); AudioSourceManagers.registerLocalSource(playerManager); + loadProperties(properties); + } + + /** + * Loads various properties from config file + * @param properties Object holding the contents of the property file + */ + private void loadProperties(Properties properties) { localFilePath = properties.getProperty("localFilePath"); followingUser = properties.getProperty("followingUser"); String temp = properties.getProperty("audioOnUserJoin"); diff --git a/usersound.properties.example b/usersound.properties.example index 9575f01..248d71c 100644 --- a/usersound.properties.example +++ b/usersound.properties.example @@ -2,3 +2,10 @@ //Discord user and the file (with extension) Queen=WeAreTheChampions.mp3 + +//We can also link to sounds in folders inside the main sound folder +Shrek=More/SmashMouth.wav + +//Map multiple people to same sound +Thing1=sawing_wood.wav +Thing2=sawing_wood.wav -- cgit v1.2.3 From d6aa077b1eda1ea5694dde0250b8b5fd21f114dd Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Fri, 6 Jul 2018 21:43:41 -0400 Subject: Cleaning things up a bit --- soundchan.properties.example | 5 +++++ src/main/java/soundchan/BotListener/BotListener.java | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/soundchan.properties.example b/soundchan.properties.example index 2ba3290..c15a89a 100644 --- a/soundchan.properties.example +++ b/soundchan.properties.example @@ -7,7 +7,12 @@ localFilePath=C:\\PATH\\TO\\SOUNDS\\DIRECTORY //The user for the followingUser=USERNAME +//Flag conditions enabled with any of the following values: +// true, on, enable, yes, 1 +//any other string (or empty) will leave the condition disabled + //If you want SoundChan to play an audio file whit their name when a user joins the channel or have that information come from below file +//This is a flag condition audioOnUserJoin=on/off //The file where users and sound clips are related, see usersound.properties.example for more info diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 7a65f78..b54edbe 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -54,8 +54,7 @@ public class BotListener extends ListenerAdapter{ private void loadProperties(Properties properties) { localFilePath = properties.getProperty("localFilePath"); followingUser = properties.getProperty("followingUser"); - String temp = properties.getProperty("audioOnUserJoin"); - audioOnUserJoin = settingEnableCheck(temp); + audioOnUserJoin = settingEnableCheck(properties.getProperty("audioOnUserJoin")); if(audioOnUserJoin) { localManager = new LocalAudioManager(localFilePath, properties.getProperty("userAudioFilePath")); } -- cgit v1.2.3