Added base java code, replacing jmusicbot script
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.idea/
|
||||||
|
**/target/
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
# Siren
|
# Siren
|
||||||
|
A Docker containerized version of [MusicBot](https://github.com/jagrosh/MusicBot)
|
||||||
|
|
||||||
`docker build .`
|
`docker build .`
|
||||||
`docker-compose up -d`
|
`docker-compose up -d`
|
||||||
101
pom.xml
Normal file
101
pom.xml
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.bensherriff</groupId>
|
||||||
|
<artifactId>Siren</artifactId>
|
||||||
|
<version>Snapshot</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>central</id>
|
||||||
|
<name>Maven Central</name>
|
||||||
|
<layout>default</layout>
|
||||||
|
<url>https://repo1.maven.org/maven2</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>dv8tion</id>
|
||||||
|
<name>m2-dv8tion</name>
|
||||||
|
<url>https://m2.dv8tion.net/releases</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Discord Dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.dv8tion</groupId>
|
||||||
|
<artifactId>JDA</artifactId>
|
||||||
|
<!-- <version>5.0.0-beta.2</version>-->
|
||||||
|
<version>4.2.1_253</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sedmelluq</groupId>
|
||||||
|
<artifactId>lavaplayer</artifactId>
|
||||||
|
<version>1.3.77</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Logging -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>2.0.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-api</artifactId>
|
||||||
|
<version>2.19.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-core</artifactId>
|
||||||
|
<version>2.19.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>1.5</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||||
|
<shadedClassifierName>All</shadedClassifierName>
|
||||||
|
<artifactSet>
|
||||||
|
<includes>
|
||||||
|
<include>*:*</include>
|
||||||
|
</includes>
|
||||||
|
</artifactSet>
|
||||||
|
<transformers>
|
||||||
|
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||||
|
<resource>reference.conf</resource>
|
||||||
|
</transformer>
|
||||||
|
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<manifestEntries>
|
||||||
|
<Main-Class>com.bensherriff.siren.MusicBot</Main-Class>
|
||||||
|
<Specification-Title>${project.artifactId}</Specification-Title>
|
||||||
|
<Specification-Version>${project.version}</Specification-Version>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Implementation-Vendor-Id>${project.groupId}</Implementation-Vendor-Id>
|
||||||
|
</manifestEntries>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
12
src/main/java/com/bensherriff/siren/AudioPlayerManager.java
Normal file
12
src/main/java/com/bensherriff/siren/AudioPlayerManager.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package com.bensherriff.siren;
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||||
|
|
||||||
|
public class AudioPlayerManager extends DefaultAudioPlayerManager {
|
||||||
|
|
||||||
|
public void initialize() {
|
||||||
|
AudioSourceManagers.registerRemoteSources(this);
|
||||||
|
AudioSourceManagers.registerLocalSource(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.bensherriff.siren;
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.track.playback.MutableAudioFrame;
|
||||||
|
import java.nio.Buffer;
|
||||||
|
import net.dv8tion.jda.api.audio.AudioSendHandler;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class AudioPlayerSendHandler implements AudioSendHandler {
|
||||||
|
private final AudioPlayer audioPlayer;
|
||||||
|
private final ByteBuffer buffer;
|
||||||
|
private final MutableAudioFrame frame;
|
||||||
|
|
||||||
|
public AudioPlayerSendHandler(AudioPlayer audioPlayer) {
|
||||||
|
this.audioPlayer = audioPlayer;
|
||||||
|
this.buffer = ByteBuffer.allocate(1024);
|
||||||
|
this.frame = new MutableAudioFrame();
|
||||||
|
this.frame.setBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canProvide() {
|
||||||
|
// returns true if audio was provided
|
||||||
|
return audioPlayer.provide(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer provide20MsAudio() {
|
||||||
|
// flip to make it a read buffer
|
||||||
|
((Buffer) buffer).flip();
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpus() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
132
src/main/java/com/bensherriff/siren/MusicBot.java
Normal file
132
src/main/java/com/bensherriff/siren/MusicBot.java
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
package com.bensherriff.siren;
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||||
|
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 net.dv8tion.jda.api.JDABuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
|
import net.dv8tion.jda.api.entities.VoiceChannel;
|
||||||
|
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
|
||||||
|
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||||
|
import net.dv8tion.jda.api.managers.AudioManager;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static net.dv8tion.jda.api.requests.GatewayIntent.GUILD_MESSAGES;
|
||||||
|
import static net.dv8tion.jda.api.requests.GatewayIntent.GUILD_VOICE_STATES;
|
||||||
|
|
||||||
|
public class MusicBot extends ListenerAdapter {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
JDABuilder.create("OTMyMzAxMjQ4NTQ2MzYxMzQ2.YeQ_Mg.n4H8Cl3dQ1u5aFL1ZvTmfcGwpEY", GUILD_MESSAGES, GUILD_VOICE_STATES)
|
||||||
|
.addEventListeners(new MusicBot())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final AudioPlayerManager playerManager;
|
||||||
|
private final Map<Long, MusicManager> musicManagers;
|
||||||
|
|
||||||
|
private MusicBot() {
|
||||||
|
this.musicManagers = new HashMap<>();
|
||||||
|
|
||||||
|
this.playerManager = new DefaultAudioPlayerManager();
|
||||||
|
AudioSourceManagers.registerRemoteSources(playerManager);
|
||||||
|
AudioSourceManagers.registerLocalSource(playerManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized MusicManager getGuildAudioPlayer(Guild guild) {
|
||||||
|
long guildId = Long.parseLong(guild.getId());
|
||||||
|
MusicManager musicManager = musicManagers.get(guildId);
|
||||||
|
|
||||||
|
if (musicManager == null) {
|
||||||
|
musicManager = new MusicManager(playerManager);
|
||||||
|
musicManagers.put(guildId, musicManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
guild.getAudioManager().setSendingHandler(musicManager.getSendHandler());
|
||||||
|
|
||||||
|
return musicManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGuildMessageReceived(GuildMessageReceivedEvent event) {
|
||||||
|
String[] command = event.getMessage().getContentRaw().split(" ", 2);
|
||||||
|
if (event.getAuthor().isBot()) return;
|
||||||
|
|
||||||
|
TextChannel channel = event.getChannel();
|
||||||
|
|
||||||
|
if ("!play".equals(command[0]) && command.length == 2) {
|
||||||
|
loadAndPlay(channel, command[1]);
|
||||||
|
} else if ("!skip".equals(command[0])) {
|
||||||
|
skipTrack(channel);
|
||||||
|
} else if ("!stop".equals(command[0])) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onGuildMessageReceived(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAndPlay(final TextChannel channel, final String trackUrl) {
|
||||||
|
MusicManager musicManager = getGuildAudioPlayer(channel.getGuild());
|
||||||
|
|
||||||
|
playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() {
|
||||||
|
@Override
|
||||||
|
public void trackLoaded(AudioTrack track) {
|
||||||
|
channel.sendMessage("Adding **" + track.getInfo().title + "** to queue").queue();
|
||||||
|
|
||||||
|
play(channel.getGuild(), musicManager, 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();
|
||||||
|
|
||||||
|
play(channel.getGuild(), musicManager, 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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void play(Guild guild, MusicManager musicManager, AudioTrack track) {
|
||||||
|
connectToFirstVoiceChannel(guild.getAudioManager());
|
||||||
|
|
||||||
|
musicManager.scheduler.queue(track);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skipTrack(TextChannel channel) {
|
||||||
|
MusicManager musicManager = getGuildAudioPlayer(channel.getGuild());
|
||||||
|
musicManager.scheduler.nextTrack();
|
||||||
|
|
||||||
|
channel.sendMessage("Skipped to next track.").queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void connectToFirstVoiceChannel(AudioManager audioManager) {
|
||||||
|
if (!audioManager.isConnected()) {
|
||||||
|
for (VoiceChannel voiceChannel : audioManager.getGuild().getVoiceChannels()) {
|
||||||
|
audioManager.openAudioConnection(voiceChannel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/main/java/com/bensherriff/siren/MusicManager.java
Normal file
20
src/main/java/com/bensherriff/siren/MusicManager.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package com.bensherriff.siren;
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||||
|
|
||||||
|
public class MusicManager {
|
||||||
|
|
||||||
|
public final AudioPlayer player;
|
||||||
|
public final TrackScheduler scheduler;
|
||||||
|
|
||||||
|
public MusicManager(AudioPlayerManager manager) {
|
||||||
|
player = manager.createPlayer();
|
||||||
|
scheduler = new TrackScheduler(player);
|
||||||
|
player.addListener(scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AudioPlayerSendHandler getSendHandler() {
|
||||||
|
return new AudioPlayerSendHandler(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/main/java/com/bensherriff/siren/TrackScheduler.java
Normal file
56
src/main/java/com/bensherriff/siren/TrackScheduler.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package com.bensherriff.siren;
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
|
||||||
|
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class schedules tracks for the audio player. It contains the queue of tracks.
|
||||||
|
*/
|
||||||
|
public class TrackScheduler extends AudioEventAdapter {
|
||||||
|
private final AudioPlayer player;
|
||||||
|
private final BlockingQueue<AudioTrack> queue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param player The audio player this scheduler uses
|
||||||
|
*/
|
||||||
|
public TrackScheduler(AudioPlayer player) {
|
||||||
|
this.player = player;
|
||||||
|
this.queue = new LinkedBlockingQueue<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the next track to queue or play right away if nothing is in the queue.
|
||||||
|
*
|
||||||
|
* @param track The track to play or add to queue.
|
||||||
|
*/
|
||||||
|
public void queue(AudioTrack track) {
|
||||||
|
// Calling startTrack with the noInterrupt set to true will start the track only if nothing is currently playing. If
|
||||||
|
// something is playing, it returns false and does nothing. In that case the player was already playing so this
|
||||||
|
// track goes to the queue instead.
|
||||||
|
if (!player.startTrack(track, true)) {
|
||||||
|
queue.offer(track);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the next track, stopping the current one if it is playing.
|
||||||
|
*/
|
||||||
|
public void nextTrack() {
|
||||||
|
// Start the next track, regardless of if something is already playing or not. In case queue was empty, we are
|
||||||
|
// giving null to startTrack, which is a valid argument and will simply stop the player.
|
||||||
|
player.startTrack(queue.poll(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
|
||||||
|
// Only start the next track if the end reason is suitable for it (FINISHED or LOAD_FAILED)
|
||||||
|
if (endReason.mayStartNext) {
|
||||||
|
nextTrack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/main/resources/log4j2.xml
Normal file
13
src/main/resources/log4j2.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Configuration status="WARN">
|
||||||
|
<Appenders>
|
||||||
|
<Console name="Console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="%d{HH:mm:ss.SSS} | %-5level | %msg%n"/>
|
||||||
|
</Console>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Root level="info">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
||||||
Reference in New Issue
Block a user