#2 Added logic to have a player for each guild

This commit is contained in:
Isaac Parenteau
2019-10-06 00:20:58 -05:00
parent 950d20b137
commit 7c5f4c6c72
9 changed files with 401 additions and 137 deletions

View File

@ -1,177 +1,97 @@
/**
*
* Project: Eight Track, File: MusicListenerAdaptor.java
*
* Copyright 2019 Locusworks LLC.
* All rights reserved. Federal copyright law prohibits unauthorized reproduction by
* any means and imposes fines up to $25,000 for violation. No part of this material
* may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
* modified, duplicated, adapted or translated into another program language in any
* form or by any means, electronic, mechanical, photocopying, recording, or
* otherwise, without the prior written permission from Locusworks. Locusworks
* affirms that Eight-Track(R) software and data is subject to United States
* Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
* Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
*
* IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
* LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
* THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
* ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
* IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*/
package net.locusworks.discord.eighttrack.adaptors;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.VoiceChannel;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.managers.AudioManager;
import net.locusworks.discord.eighttrack.handlers.EightTrackAudioSendHandler;
import net.locusworks.discord.eighttrack.main.Entry;
import net.locusworks.discord.eighttrack.scheduler.TrackScheduler;
import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler;
import net.locusworks.logger.ApplicationLogger;
import net.locusworks.logger.ApplicationLoggerFactory;
public class MusicListenerAdaptor extends ListenerAdapter {
private Path musicDir;
private TrackScheduler ts;
private DefaultAudioPlayerManager apm;
private ApplicationLogger logger;
private AudioPlayer player;
private AtomicBoolean playing;
private Map<Long, GuildMusicHandler> playerMap;
public MusicListenerAdaptor(Path musicDir) throws IOException {
this.logger = ApplicationLoggerFactory.getLogger(Entry.class);
this.playing = new AtomicBoolean(false);
this.logger = ApplicationLoggerFactory.getLogger(MusicListenerAdaptor.class);
this.playerMap = new ConcurrentHashMap<>();
this.musicDir = musicDir;
this.apm = new DefaultAudioPlayerManager();
AudioSourceManagers.registerLocalSource(apm);
this.player = apm.createPlayer();
this.ts = new TrackScheduler();
player.addListener(ts);
indexFiles();
}
@Override
public void onGuildMessageReceived(GuildMessageReceivedEvent event) {
if (event.getAuthor().isBot()) return;
try {
onGuildMessageReceivedHelper(event);
} catch (Throwable t) {
logger.error(t);
}
}
private void onGuildMessageReceivedHelper(GuildMessageReceivedEvent event) throws IOException {
if (!playerMap.containsKey(event.getGuild().getIdLong())) {
playerMap.put(event.getGuild().getIdLong(), new GuildMusicHandler(musicDir));
}
GuildMusicHandler gmh = playerMap.get(event.getGuild().getIdLong());
String command = event.getMessage().getContentRaw().trim().toLowerCase();
switch (command) {
case "-play":
playing.set(true);
play(event);
gmh.isPlaying(true);
gmh.play(event);
return;
case "-stop":
playing.set(false);
stop(event);
gmh.isPlaying(false);
gmh.stop(event);
return;
case "-next":
next(event);
gmh.next(event);
return;
case "-repeat":
playing.set(true);
repeat(event);
gmh.isPlaying(true);
gmh.repeat(event);
return;
case "-whatsnext":
whatsNext(event);
gmh.whatsNext(event);
break;
case "-index":
index(event);
gmh.index(event);
break;
default:
return;
}
}
private void indexFiles() throws IOException {
List<Path> songs = Files.walk(musicDir)
.filter(p-> p.getFileName().toString().endsWith(".mp3"))
.collect(Collectors.toList());
logger.info("Adding %d songs from directory %s", songs.size(), musicDir);
for (Path song : songs) {
logger.debug("Loading song: %s", song);
try {
apm.loadItem(song.toAbsolutePath().toString(), ts);
} catch (IllegalStateException ex) {
logger.warn("Unable to load song :%s -> %s", song.toAbsolutePath().toString(), ex.getMessage());
}
}
}
private void index(GuildMessageReceivedEvent event) {
event.getChannel().sendMessage(String.format("<@%s>, Please wait as i reindex the music files", event.getAuthor().getId())).queue();
try {
indexFiles();
} catch (IOException e) {
event.getChannel().sendMessage(String.format("<@%s>, Unable to reindex the music files: %s", event.getAuthor().getId(), e.getMessage())).queue();
return;
}
event.getChannel().sendMessage(String.format("<@%s>, Reindexing complete", event.getAuthor().getId())).queue();
}
private void whatsNext(GuildMessageReceivedEvent event) {
AudioTrack track = ts.peek();
MessageEmbed embed = new EmbedBuilder()
.setAuthor(event.getMember().getEffectiveName(), null, event.getAuthor().getAvatarUrl())
.setTitle("Next Up:")
.setDescription(String.format("**%s** by __%s__", track.getInfo().title, track.getInfo().author))
.setTimestamp(OffsetDateTime.now())
.build();
event.getChannel().sendMessage(embed).queue();
}
private void repeat(GuildMessageReceivedEvent event) {
next(event);
ts.setFinishedCallback((ater) -> {
if (!playing.get()) return;
next(event);
});
}
private void next(GuildMessageReceivedEvent event) {
stop(event);
play(event);
}
private void stop(GuildMessageReceivedEvent event) {
player.stopTrack();
}
private void play(GuildMessageReceivedEvent event) {
VoiceChannel vc = event.getMember().getVoiceState().getChannel();
if (vc == null) {
event.getChannel().sendMessage(String.format("<@%s> you are not in a voice channel to play music", event.getMember().getId())).queue();
return;
}
if (!event.getGuild().getSelfMember().hasPermission(vc, Permission.VOICE_CONNECT, Permission.VOICE_SPEAK)) {
event.getChannel().sendMessage(String.format("<@%s>, I cannot play my music in channel %s as I dont have permission to",
event.getMember().getId(), vc.getName())).queue();
return;
}
AudioManager manager = event.getGuild().getAudioManager();
manager.openAudioConnection(vc);
manager.setSendingHandler(new EightTrackAudioSendHandler(player));
if (ts.hasTracks()) {
AudioTrack track = ts.getNextTrack();
MessageEmbed embed = new EmbedBuilder()
.setAuthor(event.getMember().getEffectiveName(), null, event.getAuthor().getAvatarUrl())
.setTitle("Now Playing:")
.setDescription(String.format("**%s** by __%s__", track.getInfo().title, track.getInfo().author))
.setTimestamp(OffsetDateTime.now())
.build();
event.getChannel().sendMessage(embed).queue();
player.playTrack(track);
ts.trackLoaded(track);
}
}
}

View File

@ -1,3 +1,30 @@
/**
*
* Project: Eight Track, File: EightTrackAudioSendHandler.java
*
* Copyright 2019 Locusworks LLC.
* All rights reserved. Federal copyright law prohibits unauthorized reproduction by
* any means and imposes fines up to $25,000 for violation. No part of this material
* may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
* modified, duplicated, adapted or translated into another program language in any
* form or by any means, electronic, mechanical, photocopying, recording, or
* otherwise, without the prior written permission from Locusworks. Locusworks
* affirms that Eight-Track(R) software and data is subject to United States
* Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
* Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
*
* IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
* LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
* THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
* ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
* IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*/
package net.locusworks.discord.eighttrack.handlers;
import java.nio.ByteBuffer;

View File

@ -0,0 +1,173 @@
/**
*
* Project: Eight Track, File: GuildMusicHandler.java
*
* Copyright 2019 Locusworks LLC.
* All rights reserved. Federal copyright law prohibits unauthorized reproduction by
* any means and imposes fines up to $25,000 for violation. No part of this material
* may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
* modified, duplicated, adapted or translated into another program language in any
* form or by any means, electronic, mechanical, photocopying, recording, or
* otherwise, without the prior written permission from Locusworks. Locusworks
* affirms that Eight-Track(R) software and data is subject to United States
* Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
* Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
*
* IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
* LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
* THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
* ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
* IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*/
package net.locusworks.discord.eighttrack.handlers;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.managers.AudioManager;
import net.locusworks.discord.eighttrack.scheduler.TrackScheduler;
import net.locusworks.logger.ApplicationLogger;
import net.locusworks.logger.ApplicationLoggerFactory;
public class GuildMusicHandler {
private Path musicDir;
private TrackScheduler ts;
private DefaultAudioPlayerManager apm;
private ApplicationLogger logger;
private AudioPlayer player;
private AtomicBoolean playing;
public GuildMusicHandler(Path musicDir) throws IOException {
this.logger = ApplicationLoggerFactory.getLogger(GuildMusicHandler.class);
this.playing = new AtomicBoolean(false);
this.musicDir = musicDir;
this.apm = new DefaultAudioPlayerManager();
AudioSourceManagers.registerLocalSource(apm);
this.player = apm.createPlayer();
this.ts = new TrackScheduler();
player.addListener(ts);
indexFiles();
}
public void isPlaying(boolean playing) {
this.playing.set(playing);
}
public void indexFiles() throws IOException {
List<Path> songs = Files.walk(musicDir)
.filter(p-> p.getFileName().toString().endsWith(".mp3"))
.collect(Collectors.toList());
logger.info("Adding %d songs from directory %s", songs.size(), musicDir);
for (Path song : songs) {
logger.debug("Loading song: %s", song);
try {
apm.loadItem(song.toAbsolutePath().toString(), ts);
} catch (IllegalStateException ex) {
logger.warn("Unable to load song :%s -> %s", song.toAbsolutePath().toString(), ex.getMessage());
}
}
}
public void index(GuildMessageReceivedEvent event) {
event.getChannel().sendMessage(String.format("<@%s>, Please wait as i reindex the music files", event.getAuthor().getId())).queue();
try {
indexFiles();
} catch (IOException e) {
event.getChannel().sendMessage(String.format("<@%s>, Unable to reindex the music files: %s", event.getAuthor().getId(), e.getMessage())).queue();
return;
}
event.getChannel().sendMessage(String.format("<@%s>, Reindexing complete", event.getAuthor().getId())).queue();
}
public void whatsNext(GuildMessageReceivedEvent event) {
AudioTrack track = ts.peek();
MessageEmbed embed = new EmbedBuilder()
.setAuthor(event.getMember().getEffectiveName(), null, event.getAuthor().getAvatarUrl())
.setTitle("Next Up:")
.setDescription(String.format("**%s** by __%s__", track.getInfo().title, track.getInfo().author))
.setTimestamp(OffsetDateTime.now())
.build();
event.getChannel().sendMessage(embed).queue();
}
public void repeat(GuildMessageReceivedEvent event) {
next(event);
ts.setFinishedCallback((ater) -> {
if (!playing.get()) return;
next(event);
});
}
public void next(GuildMessageReceivedEvent event) {
playing.set(false);
stop(event);
play(event);
playing.set(true);
}
public void stop(GuildMessageReceivedEvent event) {
player.stopTrack();
}
public void play(GuildMessageReceivedEvent event) {
VoiceChannel vc = event.getMember().getVoiceState().getChannel();
if (vc == null) {
event.getChannel().sendMessage(String.format("<@%s> you are not in a voice channel to play music", event.getMember().getId())).queue();
return;
}
if (!event.getGuild().getSelfMember().hasPermission(vc, Permission.VOICE_CONNECT, Permission.VOICE_SPEAK)) {
event.getChannel().sendMessage(String.format("<@%s>, I cannot play my music in channel %s as I dont have permission to",
event.getMember().getId(), vc.getName())).queue();
return;
}
AudioManager manager = event.getGuild().getAudioManager();
manager.openAudioConnection(vc);
manager.setSendingHandler(new EightTrackAudioSendHandler(player));
if (ts.hasTracks()) {
AudioTrack track = ts.getNextTrack();
MessageEmbed embed = new EmbedBuilder()
.setAuthor(event.getMember().getEffectiveName(), null, event.getAuthor().getAvatarUrl())
.setTitle("Now Playing:")
.setDescription(String.format("**%s** by __%s__", track.getInfo().title, track.getInfo().author))
.setTimestamp(OffsetDateTime.now())
.build();
event.getChannel().sendMessage(embed).queue();
player.playTrack(track);
ts.trackLoaded(track);
}
}
}

View File

@ -1,3 +1,30 @@
/**
*
* Project: Eight Track, File: Entry.java
*
* Copyright 2019 Locusworks LLC.
* All rights reserved. Federal copyright law prohibits unauthorized reproduction by
* any means and imposes fines up to $25,000 for violation. No part of this material
* may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
* modified, duplicated, adapted or translated into another program language in any
* form or by any means, electronic, mechanical, photocopying, recording, or
* otherwise, without the prior written permission from Locusworks. Locusworks
* affirms that Eight-Track(R) software and data is subject to United States
* Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
* Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
*
* IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
* LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
* THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
* ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
* IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*/
package net.locusworks.discord.eighttrack.main;
import java.io.IOException;

View File

@ -1,3 +1,30 @@
/**
*
* Project: Eight Track, File: TrackScheduler.java
*
* Copyright 2019 Locusworks LLC.
* All rights reserved. Federal copyright law prohibits unauthorized reproduction by
* any means and imposes fines up to $25,000 for violation. No part of this material
* may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
* modified, duplicated, adapted or translated into another program language in any
* form or by any means, electronic, mechanical, photocopying, recording, or
* otherwise, without the prior written permission from Locusworks. Locusworks
* affirms that Eight-Track(R) software and data is subject to United States
* Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
* Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
*
* IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
* LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
* THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
* ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
* IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*/
package net.locusworks.discord.eighttrack.scheduler;
import java.util.Queue;

View File

@ -12,7 +12,7 @@
</Console>
<RollingFile name="eighttrack"
fileName="eighttrack.log"
filePattern="eighttrackLO-%d{yyyy-MM-dd}.log.gz">
filePattern="eighttrack-%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="${logFormat}" />
<Policies>
<TimeBasedTriggeringPolicy />