v0.1.4 - Built out slash commands

This commit is contained in:
2023-01-23 17:17:33 -05:00
parent 35687e6e02
commit 2e3e44ad58
7 changed files with 193 additions and 59 deletions

View File

@@ -1,6 +1,19 @@
# Siren # Siren
A Java/Docker Discord music bot A Java/Docker Discord music bot
## Running
Visit the [Discord Developer Portal](https://discord.com/developers/applications) and create a new application.
Guides and more information are available [here](https://discord.com/developers/docs/intro).
### OAuth2 URL Generator
The bot requires the following permissions/scopes:
- bot
- applications.commands
```
https://discord.com/api/oauth2/authorize?client_id=<Client ID>&permissions=1088840792896&scope=applications.commands%20bot
```
`docker build -t siren .` `docker build -t siren .`
`docker-compose up -d` `docker-compose up -d`

View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.bensherriff</groupId> <groupId>com.bensherriff</groupId>
<artifactId>siren</artifactId> <artifactId>siren</artifactId>
<version>0.1.3</version> <version>0.1.4</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<repositories> <repositories>

View File

@@ -1,6 +1,7 @@
package com.bensherriff.siren; package com.bensherriff.siren;
import com.bensherriff.siren.listener.Listener; import com.bensherriff.siren.listener.Listener;
import com.bensherriff.siren.listener.SlashListener;
import com.bensherriff.siren.listener.TextListener; import com.bensherriff.siren.listener.TextListener;
import com.bensherriff.siren.settings.Settings; import com.bensherriff.siren.settings.Settings;
import com.bensherriff.siren.settings.SettingsManager; import com.bensherriff.siren.settings.SettingsManager;
@@ -38,7 +39,8 @@ public class MusicBot {
private static void start() throws IOException, LoginException { private static void start() throws IOException, LoginException {
SettingsManager settingsManager = new SettingsManager(); SettingsManager settingsManager = new SettingsManager();
Settings settings = settingsManager.load(); Settings settings = settingsManager.load();
listener = new TextListener(settings); // listener = new TextListener(settings);
listener = new SlashListener(settings);
JDA jda = JDABuilder.create(settings.getToken(), Arrays.asList(INTENTS)) JDA jda = JDABuilder.create(settings.getToken(), Arrays.asList(INTENTS))
.enableCache(Arrays.asList(ENABLED_FLAGS)) .enableCache(Arrays.asList(ENABLED_FLAGS))

View File

@@ -1,6 +1,7 @@
package com.bensherriff.siren.listener; package com.bensherriff.siren.listener;
import com.bensherriff.siren.audio.AudioHandler; import com.bensherriff.siren.audio.AudioHandler;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import java.util.ArrayList; import java.util.ArrayList;
@@ -10,6 +11,7 @@ public class CommandEvent {
private final String command; private final String command;
private final String userId; private final String userId;
private final Guild guild;
private final List<String> args = new ArrayList<>(); private final List<String> args = new ArrayList<>();
private final AudioHandler audioHandler; private final AudioHandler audioHandler;
private final TextChannel textChannel; private final TextChannel textChannel;
@@ -17,6 +19,7 @@ public class CommandEvent {
private CommandEvent(CommandBuilder builder) { private CommandEvent(CommandBuilder builder) {
this.command = builder.command; this.command = builder.command;
this.userId = builder.userId; this.userId = builder.userId;
this.guild = builder.guild;
this.args.addAll(builder.args); this.args.addAll(builder.args);
this.audioHandler = builder.audioHandler; this.audioHandler = builder.audioHandler;
this.textChannel = builder.textChannel; this.textChannel = builder.textChannel;
@@ -30,6 +33,10 @@ public class CommandEvent {
return userId; return userId;
} }
public Guild getGuild() {
return guild;
}
public List<String> getArgs() { public List<String> getArgs() {
return args; return args;
} }
@@ -45,6 +52,7 @@ public class CommandEvent {
public static class CommandBuilder { public static class CommandBuilder {
private final String command; private final String command;
private final String userId; private final String userId;
private Guild guild;
private List<String> args = new ArrayList<>(); private List<String> args = new ArrayList<>();
private AudioHandler audioHandler; private AudioHandler audioHandler;
private TextChannel textChannel; private TextChannel textChannel;
@@ -54,6 +62,11 @@ public class CommandEvent {
this.userId = userId; this.userId = userId;
} }
public CommandBuilder setGuild(Guild guild) {
this.guild = guild;
return this;
}
public CommandBuilder setArgs(List<String> args) { public CommandBuilder setArgs(List<String> args) {
this.args = args; this.args = args;
return this; return this;

View File

@@ -80,76 +80,36 @@ public abstract class Listener extends ListenerAdapter {
super.onReady(event); super.onReady(event);
} }
protected void loadAndPlay(final TextChannel channel, final String userID, final String trackUrl) {
AudioHandler audioHandler = getGuildAudioPlayer(channel.getGuild());
playerManager.loadItemOrdered(audioHandler, trackUrl, new AudioLoadResultHandler() {
@Override
public void trackLoaded(AudioTrack track) {
channel.sendMessage("Adding **" + track.getInfo().title + "** to queue").queue();
playTrack(channel.getGuild(), userID, audioHandler, track);
}
@Override
public void playlistLoaded(AudioPlaylist playlist) {
AudioTrack firstTrack = playlist.getSelectedTrack();
if (firstTrack == null) {
firstTrack = playlist.getTracks().get(0);
}
channel.sendMessage("Adding **" + firstTrack.getInfo().title + "** to queue (first track of playlist " + playlist.getName() + ")").queue();
playTrack(channel.getGuild(), userID, audioHandler, firstTrack);
}
@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();
}
});
}
protected void playTrack(Guild guild, String userID, AudioHandler audioHandler, AudioTrack track) { protected void playTrack(Guild guild, String userID, AudioHandler audioHandler, AudioTrack track) {
connectToVoiceChannel(userID, guild.getAudioManager()); connectToVoiceChannel(userID, guild.getAudioManager());
audioHandler.addTrack(track); audioHandler.addTrack(track);
} }
protected void stopTrack(TextChannel channel) { protected void stopTrack(Guild guild) {
AudioHandler audioHandler = getGuildAudioPlayer(channel.getGuild()); AudioHandler audioHandler = getGuildAudioPlayer(guild);
audioHandler.stopTrack(); audioHandler.stopTrack();
channel.getGuild().getAudioManager().closeAudioConnection(); guild.getAudioManager().closeAudioConnection();
channel.sendMessage("Stopping music").queue();
} }
protected void skipTrack(TextChannel channel) { protected void skipTrack(Guild guild) {
AudioHandler audioHandler = getGuildAudioPlayer(channel.getGuild()); AudioHandler audioHandler = getGuildAudioPlayer(guild);
audioHandler.stopTrack(); audioHandler.stopTrack();
channel.sendMessage("Skipped to next track").queue();
} }
protected void pauseTrack(TextChannel channel) { protected void pauseTrack(Guild guild) {
AudioHandler audioHandler = getGuildAudioPlayer(channel.getGuild()); AudioHandler audioHandler = getGuildAudioPlayer(guild);
audioHandler.setPaused(true); audioHandler.setPaused(true);
channel.sendMessage("Paused track").queue();
} }
protected void resumeTrack(TextChannel channel) { protected void resumeTrack(Guild guild) {
AudioHandler audioHandler = getGuildAudioPlayer(channel.getGuild()); AudioHandler audioHandler = getGuildAudioPlayer(guild);
audioHandler.setPaused(false); audioHandler.setPaused(false);
channel.sendMessage("Resumed track").queue();
} }
protected void changeVolume(TextChannel channel, String vol) { protected void changeVolume(Guild guild, int volume) {
AudioHandler audioHandler = getGuildAudioPlayer(channel.getGuild()); AudioHandler audioHandler = getGuildAudioPlayer(guild);
int volume = Integer.parseInt(vol);
getSettings().setVolume(volume); getSettings().setVolume(volume);
audioHandler.setVolume(volume); audioHandler.setVolume(volume);
channel.sendMessage("Set volume to " + volume).queue();
} }
private void connectToVoiceChannel(String userID, AudioManager audioManager) { private void connectToVoiceChannel(String userID, AudioManager audioManager) {

View File

@@ -1,17 +1,116 @@
package com.bensherriff.siren.listener; package com.bensherriff.siren.listener;
import com.bensherriff.siren.audio.AudioHandler;
import com.bensherriff.siren.settings.Settings; import com.bensherriff.siren.settings.Settings;
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.session.ReadyEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public class SlashListener extends Listener { public class SlashListener extends Listener {
public SlashListener(Settings settings) { public SlashListener(Settings settings) {
super(settings); super(settings);
} }
@Override
public void onReady(@NotNull ReadyEvent event) {
jda.getGuilds().forEach(guild -> {
guild.updateCommands().addCommands(
Commands.slash("play", "Play a track from a URL")
.addOption(OptionType.STRING, "url", "Track URL", true),
Commands.slash("skip", "Skip the current track"),
Commands.slash("stop", "Stop playing tracks and clear the queue"),
Commands.slash("volume", "Set the volume")
.addOption(OptionType.INTEGER, "volume", "Updated Volume", true),
Commands.slash("pause", "Pause the current track"),
Commands.slash("resume", "Resume the current paused track")
).queue();
});
super.onReady(event);
}
@Override @Override
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) { public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
String userId = event.getUser().getId();
Guild guild = event.getGuild();
String command = event.getName();
event.deferReply().queue();
switch (command) {
case "play" -> {
String trackURL = Objects.requireNonNull(event.getOption("url")).getAsString();
loadAndPlay(guild, userId, trackURL, event);
}
case "skip" -> {
skipTrack(guild);
event.getHook().sendMessage("Skipped to the next track").queue();
}
case "stop" -> {
stopTrack(guild);
event.getHook().sendMessage("Stopped track and cleared queue").queue();
}
case "volume" -> {
int volume = Objects.requireNonNull(event.getOption("volume")).getAsInt();
changeVolume(guild, volume);
event.getHook().sendMessage("Set volume to " + volume).queue();
}
case "pause" -> {
pauseTrack(guild);
event.getHook().sendMessage("Pausing track").queue();
}
case "resume" -> {
resumeTrack(guild);
event.getHook().sendMessage("Resumed track").queue();
}
default -> {
event.getHook().sendMessage("Invalid command").queue();
}
}
super.onSlashCommandInteraction(event); super.onSlashCommandInteraction(event);
} }
private void loadAndPlay(Guild guild, final String userID, final String trackUrl, SlashCommandInteractionEvent event) {
AudioHandler audioHandler = getGuildAudioPlayer(guild);
playerManager.loadItemOrdered(audioHandler, trackUrl, new AudioLoadResultHandler() {
@Override
public void trackLoaded(AudioTrack track) {
event.getHook().sendMessage("Adding **" + track.getInfo().title + "** to queue").queue();
playTrack(guild, userID, audioHandler, track);
}
@Override
public void playlistLoaded(AudioPlaylist playlist) {
AudioTrack firstTrack = playlist.getSelectedTrack();
if (firstTrack == null) {
firstTrack = playlist.getTracks().get(0);
}
event.getHook().sendMessage("Adding **" + firstTrack.getInfo().title + "** to queue (first track of playlist " + playlist.getName() + ")").queue();
playTrack(guild, userID, audioHandler, firstTrack);
}
@Override
public void noMatches() {
event.getHook().sendMessage("Nothing found by " + trackUrl).queue();
}
@Override
public void loadFailed(FriendlyException exception) {
event.getHook().sendMessage("Could not play: " + exception.getMessage()).queue();
}
});
}
} }

View File

@@ -2,6 +2,11 @@ package com.bensherriff.siren.listener;
import com.bensherriff.siren.audio.AudioHandler; import com.bensherriff.siren.audio.AudioHandler;
import com.bensherriff.siren.settings.Settings; import com.bensherriff.siren.settings.Settings;
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -21,10 +26,12 @@ public class TextListener extends Listener {
String[] command = event.getMessage().getContentRaw().split(" "); String[] command = event.getMessage().getContentRaw().split(" ");
TextChannel channel = event.getChannel().asTextChannel(); TextChannel channel = event.getChannel().asTextChannel();
String userID = event.getAuthor().getId(); String userID = event.getAuthor().getId();
AudioHandler audioHandler = getGuildAudioPlayer(channel.getGuild()); Guild guild = channel.getGuild();
AudioHandler audioHandler = getGuildAudioPlayer(guild);
CommandEvent commandEvent = new CommandEvent.CommandBuilder(command[0], userID) CommandEvent commandEvent = new CommandEvent.CommandBuilder(command[0], userID)
.setTextChannel(channel) .setTextChannel(channel)
.setGuild(guild)
.setAudioHandler(audioHandler) .setAudioHandler(audioHandler)
.setArgs(Arrays.asList(command).subList(1, command.length)) .setArgs(Arrays.asList(command).subList(1, command.length))
.build(); .build();
@@ -32,17 +39,57 @@ public class TextListener extends Listener {
if ("!play".equals(command[0]) && command.length == 2) { if ("!play".equals(command[0]) && command.length == 2) {
loadAndPlay(channel, userID, command[1]); loadAndPlay(channel, userID, command[1]);
} else if ("!skip".equals(command[0])) { } else if ("!skip".equals(command[0])) {
skipTrack(channel); skipTrack(guild);
channel.sendMessage("Skipped to the next track").queue();
} else if ("!stop".equals(command[0])) { } else if ("!stop".equals(command[0])) {
stopTrack(channel); stopTrack(guild);
channel.sendMessage("Stopped track and cleared queue").queue();
} else if ("!volume".equals(command[0]) && command.length == 2) { } else if ("!volume".equals(command[0]) && command.length == 2) {
changeVolume(channel, command[1]); int volume = Integer.parseInt(command[1]);
changeVolume(guild, volume);
channel.sendMessage("Set volume to " + command[1]).queue();
} else if ("!pause".equals(command[0])) { } else if ("!pause".equals(command[0])) {
pauseTrack(channel); pauseTrack(guild);
channel.sendMessage("Paused track").queue();
} else if ("!resume".equals(command[0])) { } else if ("!resume".equals(command[0])) {
resumeTrack(channel); resumeTrack(guild);
channel.sendMessage("Resumed track").queue();
} }
super.onMessageReceived(event); super.onMessageReceived(event);
} }
private void loadAndPlay(final TextChannel channel, final String userID, final String trackUrl) {
AudioHandler audioHandler = getGuildAudioPlayer(channel.getGuild());
playerManager.loadItemOrdered(audioHandler, trackUrl, new AudioLoadResultHandler() {
@Override
public void trackLoaded(AudioTrack track) {
channel.sendMessage("Adding **" + track.getInfo().title + "** to queue").queue();
playTrack(channel.getGuild(), userID, audioHandler, track);
}
@Override
public void playlistLoaded(AudioPlaylist playlist) {
AudioTrack firstTrack = playlist.getSelectedTrack();
if (firstTrack == null) {
firstTrack = playlist.getTracks().get(0);
}
channel.sendMessage("Adding **" + firstTrack.getInfo().title + "** to queue (first track of playlist " + playlist.getName() + ")").queue();
playTrack(channel.getGuild(), userID, audioHandler, firstTrack);
}
@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();
}
});
}
} }