2018-10-14 14:16:14 +02:00
package nl.voidcorp.dbot.music
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter
2018-10-15 22:25:51 +02:00
import com.sedmelluq.discord.lavaplayer.source.http.HttpAudioTrack
2018-10-14 22:20:47 +02:00
import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioSourceManager
import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioTrack
import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack
2018-10-14 14:16:14 +02:00
import com.sedmelluq.discord.lavaplayer.track.AudioTrack
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason
import net.dv8tion.jda.core.EmbedBuilder
2018-10-15 22:25:51 +02:00
import net.dv8tion.jda.core.entities.*
2018-10-14 14:16:14 +02:00
import nl.voidcorp.dbot.log
2018-10-14 22:20:47 +02:00
import java.awt.Color
2018-10-14 14:16:14 +02:00
import java.time.LocalDateTime
import java.util.*
2018-10-15 22:25:51 +02:00
import kotlin.concurrent.timerTask
2018-10-14 14:16:14 +02:00
class TrackScheduler ( val player : AudioPlayer , val guild : Guild , channel : VoiceChannel ) : AudioEventAdapter ( ) {
val musicChannel : TextChannel
2018-10-14 22:20:47 +02:00
2018-10-14 14:16:14 +02:00
init {
player . addListener ( this )
val audio = guild . audioManager
audio . sendingHandler = AudioPlayerSendHandler ( player )
audio . openAudioConnection ( channel )
2018-10-20 22:10:44 +02:00
musicChannel = guild . getTextChannelsByName ( " music-bot " , true ) . firstOrNull ( )
?: ( guild . getTextChannelsByName ( " music " , true ) . firstOrNull ( )
?: ( guild . getTextChannelsByName ( " bot " , true ) . firstOrNull ( )
?: ( guild . getTextChannelsByName ( " general " , true ) . firstOrNull ( )
?: guild . defaultChannel !! ) ) )
2018-10-14 14:16:14 +02:00
}
private val q = ArrayDeque < AudioTrack > ( )
/ * override fun onEvent ( event : AudioEvent ) {
if ( event is TrackEndEvent ) {
}
} * /
override fun onTrackEnd ( player : AudioPlayer , track : AudioTrack , endReason : AudioTrackEndReason ) {
if ( q . isNotEmpty ( ) ) {
2018-10-14 22:20:47 +02:00
player . playTrack ( q . poll ( ) )
2018-10-14 14:16:14 +02:00
} else {
stopPlay ( endReason )
player . destroy ( )
}
}
override fun onTrackStart ( player : AudioPlayer , track : AudioTrack ) {
2018-10-15 22:25:51 +02:00
musicChannel . sendMessage ( getCurrentTrackInfo ( ) ) . append ( " Now playing " ) . queue ( )
/ * if ( track is YoutubeAudioTrack ) {
2018-10-14 22:20:47 +02:00
if ( track . userData is Member )
} else if ( track is SoundCloudAudioTrack ) {
val scsm = track . sourceManager as SoundCloudAudioSourceManager
scsm . updateClientId ( )
val art = khttp . get ( " http://api.soundcloud.com/tracks/ ${track.info.identifier} ?client_id= ${scsm.clientId} " , headers = mapOf ( " Content-Type " to " application/json " ) ) . jsonObject [ " artwork_url " ] . toString ( ) . replace ( " large " , " t300x300 " )
if ( track . userData is Member )
musicChannel . sendMessage ( EmbedBuilder ( )
. setFooter ( " Requested by ${(track.userData as Member).effectiveName} " , ( track . userData as Member )
. user . effectiveAvatarUrl ) . setAuthor ( track . info . author ) . setTitle ( track . info . title , track . info . uri )
. setThumbnail ( art )
. setTimestamp ( LocalDateTime . now ( ) ) . setColor ( Color . decode ( " #ff8800 " ) ) . build ( ) ) . append ( " Now playing " ) . queue ( )
}
2018-10-15 22:25:51 +02:00
* /
2018-10-14 14:16:14 +02:00
}
fun queue ( track : AudioTrack , member : Member ) {
track . userData = member
if ( q . isEmpty ( ) && player . playingTrack == null ) {
log . info ( " Queue is empty, playing a track " )
player . playTrack ( track )
} else {
log . info ( " Track Queue'd " )
2018-10-14 22:20:47 +02:00
q . offer ( track )
2018-10-14 14:16:14 +02:00
}
}
fun insertFront ( track : AudioTrack , member : Member ) {
track . userData = member
if ( q . isEmpty ( ) && player . playingTrack == null ) {
log . info ( " Queue is empty, playing a track " )
player . playTrack ( track )
} else {
log . info ( " Track inserted " )
2018-10-14 22:20:47 +02:00
q . push ( track )
2018-10-14 14:16:14 +02:00
}
}
fun skip ( ) {
2018-10-14 22:20:47 +02:00
/ * if ( q . isNotEmpty ( ) ) {
2018-10-14 14:16:14 +02:00
log . info ( " skipped Track! " )
player . playTrack ( q . remove ( ) )
} else {
stopPlay ( AudioTrackEndReason . REPLACED )
player . destroy ( )
2018-10-14 22:20:47 +02:00
} * /
player . stopTrack ( )
2018-10-14 14:16:14 +02:00
}
fun isQueueEmpty ( ) = q . isEmpty ( )
2018-10-14 22:20:47 +02:00
fun isSongPlaying ( ) = player . playingTrack != null
2018-10-14 14:16:14 +02:00
fun stopPlay ( endReason : AudioTrackEndReason ) {
if ( endReason != AudioTrackEndReason . REPLACED ) {
guildMusicMap . remove ( guild . idLong )
2018-10-14 22:20:47 +02:00
musicChannel . sendMessage ( EmbedBuilder ( ) . setColor ( musicChannel . guild . selfMember . color ) . setTitle ( " I'm done here " ) . setDescription ( " There are no more songs left in the queue. " ) . setTimestamp ( LocalDateTime . now ( ) ) . build ( ) ) . queue ( )
2018-10-15 22:25:51 +02:00
Timer ( ) . schedule ( timerTask {
guild . audioManager . closeAudioConnection ( )
} , 2000 )
}
}
fun getCurrentTrackInfo ( ) : MessageEmbed = getTrackInfo ( player . playingTrack )
fun getTrackInfo ( track : AudioTrack ) : MessageEmbed {
if ( track is YoutubeAudioTrack ) {
if ( track . userData is Member )
return EmbedBuilder ( )
. setFooter ( " Requested by ${(track.userData as Member).effectiveName} " , ( track . userData as Member )
. user . effectiveAvatarUrl ) . setAuthor ( track . info . author ) . setTitle ( track . info . title , track . info . uri )
. setThumbnail ( " https://img.youtube.com/vi/ ${track.info.identifier} /hqdefault.jpg " )
. setTimestamp ( LocalDateTime . now ( ) ) . setColor ( Color . decode ( " #ff0000 " ) ) . build ( )
} else if ( track is SoundCloudAudioTrack ) {
val scsm = track . sourceManager as SoundCloudAudioSourceManager
scsm . updateClientId ( )
val art = khttp . get ( " http://api.soundcloud.com/tracks/ ${track.info.identifier} ?client_id= ${scsm.clientId} " , headers = mapOf ( " Content-Type " to " application/json " ) ) . jsonObject [ " artwork_url " ] . toString ( ) . replace ( " large " , " t300x300 " )
if ( track . userData is Member )
return EmbedBuilder ( )
. setFooter ( " Requested by ${(track.userData as Member).effectiveName} " , ( track . userData as Member )
. user . effectiveAvatarUrl ) . setAuthor ( track . info . author ) . setTitle ( track . info . title , track . info . uri )
2018-10-17 21:15:09 +02:00
. setThumbnail ( if ( art == " null " ) null else art )
2018-10-15 22:25:51 +02:00
. setTimestamp ( LocalDateTime . now ( ) ) . setColor ( Color . decode ( " #ff5500 " ) ) . build ( )
2018-10-17 21:15:09 +02:00
} else if ( track is HttpAudioTrack ) {
2018-10-15 22:25:51 +02:00
if ( track . userData is Member )
return EmbedBuilder ( )
. setFooter ( " Requested by ${(track.userData as Member).effectiveName} " , ( track . userData as Member )
. user . effectiveAvatarUrl ) . setAuthor ( track . info . author ) . setTitle ( track . info . title , track . info . uri )
. setTimestamp ( LocalDateTime . now ( ) ) . setColor ( Color . decode ( " #005A9C " ) ) . build ( )
2018-10-14 14:16:14 +02:00
}
2018-10-15 22:25:51 +02:00
return EmbedBuilder ( )
. setFooter ( " Requested by ${(track.userData as Member).effectiveName} " , ( track . userData as Member )
. user . effectiveAvatarUrl ) . setAuthor ( track . info . author ) . setTitle ( track . info . title , track . info . uri )
. setTimestamp ( LocalDateTime . now ( ) ) . setColor ( musicChannel . guild . selfMember . color ) . build ( )
}
fun getTrackList ( member : Member ) : MessageEmbed {
return EmbedBuilder ( ) . setTitle ( " Hey ${member.effectiveName} , here is the playlist " ) . setTimestamp ( LocalDateTime . now ( ) ) . setColor ( musicChannel . guild . selfMember . color )
. setFooter ( " Requested by ${member.effectiveName} " , member . user . effectiveAvatarUrl ) . setDescription (
" ** ${player.playingTrack.info.title} **, requested by ${if (player.playingTrack.userData is Member) (player.playingTrack.userData as Member).effectiveName else "someone unknown..."} (*now playing*) \n " +
q . joinToString ( separator = " \n " ) { " ** ${it.info.title} **, requested by ${if (it.userData is Member) (it.userData as Member).effectiveName else "someone unknown..."} " }
) . build ( )
2018-10-14 14:16:14 +02:00
}
}