diff --git a/pom.xml b/pom.xml index af82e02b..c32497f1 100644 --- a/pom.xml +++ b/pom.xml @@ -54,19 +54,14 @@ bintray https://jcenter.bintray.com + + ll-releases + Lavalink Releases + https://maven.lavalink.dev/releases + - - dev.schlaubi.lavakord - jda-jvm - 5.1.7 - - - dev.schlaubi.lavakord - lavasrc-jvm - 6.0.0 - ch.qos.logback logback-classic @@ -82,6 +77,11 @@ JDA 5.0.0-beta.17 + + dev.arbjerg + lavalink-client + 2.1.0 + org.json json @@ -296,10 +296,6 @@ com.github.bombies jda-ktx - - dev.schlaubi.lavakord - jda-jvm - net.dv8tion JDA diff --git a/src/main/kotlin/api/routes/requestchannel/RequestChannelService.kt b/src/main/kotlin/api/routes/requestchannel/RequestChannelService.kt index 5abae827..fc89f1c6 100644 --- a/src/main/kotlin/api/routes/requestchannel/RequestChannelService.kt +++ b/src/main/kotlin/api/routes/requestchannel/RequestChannelService.kt @@ -56,7 +56,6 @@ class RequestChannelService(shardManager: ShardManager) : AbstractGuildService(s RequestChannelEditCommand() .handleChannelButtonToggle(guild, listOf(dto.button.lowercase()), shardManager = shardManager) - ?.await() return OkResponse("Successfully toggled the ${dto.button} button in ${guild.name}") } diff --git a/src/main/kotlin/main/audiohandlers/GuildDisconnectManager.kt b/src/main/kotlin/main/audiohandlers/GuildDisconnectManager.kt index 3c38671b..c1bbea89 100644 --- a/src/main/kotlin/main/audiohandlers/GuildDisconnectManager.kt +++ b/src/main/kotlin/main/audiohandlers/GuildDisconnectManager.kt @@ -23,7 +23,7 @@ class GuildDisconnectManager(private val guild: Guild) { * @param announceMsg Whether the bot should announce that it has disconnected due to activity or not. * @param duration The time the bot should wait before disconnect. Default to 5 minutes */ - suspend fun scheduleDisconnect(duration: Duration = 5.minutes, announceMsg: Boolean = true) { + fun scheduleDisconnect(duration: Duration = 5.minutes, announceMsg: Boolean = true) { val botVoiceState = guild.selfMember.voiceState if (botVoiceState == null || !botVoiceState.inAudioChannel()) return diff --git a/src/main/kotlin/main/audiohandlers/GuildMusicManager.kt b/src/main/kotlin/main/audiohandlers/GuildMusicManager.kt index 0139cad9..bae1339a 100644 --- a/src/main/kotlin/main/audiohandlers/GuildMusicManager.kt +++ b/src/main/kotlin/main/audiohandlers/GuildMusicManager.kt @@ -1,25 +1,35 @@ package main.audiohandlers -import dev.schlaubi.lavakord.audio.Link +import dev.arbjerg.lavalink.client.LavalinkPlayer +import dev.arbjerg.lavalink.client.Link +import dev.arbjerg.lavalink.protocol.v4.Filters import main.commands.slashcommands.audio.SkipCommand import main.main.Robertify import main.utils.json.requestchannel.RequestChannelConfig import net.dv8tion.jda.api.entities.Guild class GuildMusicManager(val guild: Guild) { - val link: Link = Robertify.lavaKord.getLink(guild.id) - val player = link.player + val link: Link = Robertify.lavalink.getLink(guild.idLong) val scheduler = TrackScheduler(guild, link) val voteSkipManager = GuildVoteSkipManager() + val player: LavalinkPlayer? + get() = link.getPlayer().block() var isForcePaused = false - suspend fun clear() { + fun usePlayer(playerCallback: (LavalinkPlayer) -> Unit) { + link.getPlayer().subscribe(playerCallback) + } + + + fun clear() { val queueHandler = scheduler.queueHandler queueHandler.clear() queueHandler.clearSavedQueue() queueHandler.clearPreviousTracks() - player.filters.reset() + + link.createOrUpdatePlayer() + .setFilters(Filters()) queueHandler.trackRepeating = false queueHandler.queueRepeating = false @@ -29,13 +39,8 @@ class GuildMusicManager(val guild: Guild) { RequestChannelConfig(guild).updateMessage() } - suspend fun leave() { + fun leave() { clear() RobertifyAudioManager.removeMusicManager(guild) } - - suspend fun destroy() { - if (link.state != Link.State.DESTROYED) - link.destroy() - } } \ No newline at end of file diff --git a/src/main/kotlin/main/audiohandlers/QueueHandler.kt b/src/main/kotlin/main/audiohandlers/QueueHandler.kt index c885050b..5e046f3b 100644 --- a/src/main/kotlin/main/audiohandlers/QueueHandler.kt +++ b/src/main/kotlin/main/audiohandlers/QueueHandler.kt @@ -1,6 +1,6 @@ package main.audiohandlers -import dev.arbjerg.lavalink.protocol.v4.Track +import dev.arbjerg.lavalink.client.protocol.Track import java.util.Stack import java.util.concurrent.ConcurrentLinkedQueue diff --git a/src/main/kotlin/main/audiohandlers/RobertifyAudioManager.kt b/src/main/kotlin/main/audiohandlers/RobertifyAudioManager.kt index 461b2230..07ecd046 100644 --- a/src/main/kotlin/main/audiohandlers/RobertifyAudioManager.kt +++ b/src/main/kotlin/main/audiohandlers/RobertifyAudioManager.kt @@ -9,8 +9,8 @@ import com.github.topi314.lavasrc.spotify.SpotifySourceManager import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers +import dev.arbjerg.lavalink.client.LinkState import dev.minn.jda.ktx.util.SLF4J -import dev.schlaubi.lavakord.audio.Link import main.audiohandlers.loaders.AutoPlayLoader import main.audiohandlers.loaders.MainAudioLoader import main.audiohandlers.loaders.SearchResultLoader @@ -18,7 +18,6 @@ import main.constants.Toggle import main.main.Config import main.utils.RobertifyEmbedUtils import main.utils.RobertifyEmbedUtils.Companion.editEmbed -import main.utils.json.guildconfig.GuildConfig import main.utils.json.restrictedchannels.RestrictedChannelsConfig import main.utils.json.toggles.TogglesConfig import main.utils.locale.LocaleManager @@ -28,12 +27,10 @@ import net.dv8tion.jda.api.entities.Guild import net.dv8tion.jda.api.entities.GuildVoiceState import net.dv8tion.jda.api.entities.Message import net.dv8tion.jda.api.entities.User -import net.dv8tion.jda.api.entities.channel.ChannelType import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel import net.dv8tion.jda.api.exceptions.InsufficientPermissionException import net.dv8tion.jda.api.interactions.InteractionHook -import java.lang.IllegalArgumentException import java.util.* object RobertifyAudioManager { @@ -88,12 +85,12 @@ object RobertifyAudioManager { fun getMusicManager(guild: Guild): GuildMusicManager = get(guild) - suspend fun removeMusicManager(guild: Guild) { - musicManagers[guild.idLong]?.destroy() + fun removeMusicManager(guild: Guild) { musicManagers.remove(guild.idLong) + guild.jda.directAudioController.disconnect(guild) } - suspend fun loadAndPlay( + fun loadAndPlay( trackUrl: String, memberVoiceState: GuildVoiceState, botMessage: Message? = null, @@ -120,7 +117,7 @@ object RobertifyAudioManager { } } -// suspend fun loadAndResume(musicManager: GuildMusicManager, data: ResumeData) { +// fun loadAndResume(musicManager: GuildMusicManager, data: ResumeData) { // val channelId = data.channel_id // val voiceChannel = Robertify.shardManager.getVoiceChannelById(channelId) // @@ -137,7 +134,7 @@ object RobertifyAudioManager { // else logger.warn("Could not resume tracks in ${musicManager.guild.name} because I couldn't join the voice channel!") // } // -// private suspend fun resumeTracks( +// private fun resumeTracks( // trackList: List, // announcementChannel: GuildMessageChannel?, // musicManager: GuildMusicManager @@ -156,7 +153,7 @@ object RobertifyAudioManager { // ).loadItem() // } - private suspend fun loadTrack( + private fun loadTrack( trackUrl: String, musicManager: GuildMusicManager, user: User, @@ -176,7 +173,7 @@ object RobertifyAudioManager { ).loadItem() } - suspend fun loadSearchResults( + fun loadSearchResults( musicManager: GuildMusicManager, searcher: User, botMessage: InteractionHook, @@ -190,7 +187,7 @@ object RobertifyAudioManager { ).loadItem() } - suspend fun loadRecommendedTracks( + fun loadRecommendedTracks( musicManager: GuildMusicManager, channel: GuildMessageChannel?, trackIds: String @@ -211,7 +208,7 @@ object RobertifyAudioManager { * @param message The message to edit for any error messages. * @return True if the bot successfully joined the channel and vice-versa. */ - suspend fun joinAudioChannel( + fun joinAudioChannel( channel: AudioChannel, musicManager: GuildMusicManager, message: Message? = null, @@ -220,7 +217,7 @@ object RobertifyAudioManager { try { require(channel.members.size > 0) { "I can't join a voice channel with no one in it!" } when (musicManager.link.state) { - Link.State.DESTROYED, Link.State.NOT_CONNECTED -> { + LinkState.DISCONNECTED -> { val guild = musicManager.guild if (TogglesConfig(guild).getToggle(Toggle.RESTRICTED_VOICE_CHANNELS)) { val restrictedChannelConfig = RestrictedChannelsConfig(guild) @@ -268,7 +265,7 @@ object RobertifyAudioManager { return true } - Link.State.CONNECTED, Link.State.CONNECTING -> return true + LinkState.CONNECTED, LinkState.CONNECTING -> return true else -> { return false } diff --git a/src/main/kotlin/main/audiohandlers/TrackScheduler.kt b/src/main/kotlin/main/audiohandlers/TrackScheduler.kt index 595f5613..84fb2f50 100644 --- a/src/main/kotlin/main/audiohandlers/TrackScheduler.kt +++ b/src/main/kotlin/main/audiohandlers/TrackScheduler.kt @@ -1,23 +1,18 @@ package main.audiohandlers -import dev.arbjerg.lavalink.protocol.v4.Track +import dev.arbjerg.lavalink.client.* +import dev.arbjerg.lavalink.client.protocol.Track import dev.arbjerg.lavalink.protocol.v4.TrackInfo -import dev.minn.jda.ktx.coroutines.await -import dev.schlaubi.lavakord.audio.* -import dev.schlaubi.lavakord.audio.player.Player -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.MissingFieldException import main.audiohandlers.models.Requester import main.audiohandlers.utils.artworkUrl -import main.audiohandlers.utils.author -import main.audiohandlers.utils.title import main.commands.slashcommands.misc.PlaytimeCommand import main.constants.Toggle import main.main.Robertify -import main.utils.GeneralUtils +import main.utils.GeneralUtils.queueAfter import main.utils.RobertifyEmbedUtils import main.utils.api.robertify.imagebuilders.AbstractImageBuilder import main.utils.api.robertify.imagebuilders.ImageBuilderException @@ -45,79 +40,101 @@ import net.dv8tion.jda.api.utils.FileUpload import org.slf4j.LoggerFactory import java.io.InputStream import java.util.concurrent.CompletableFuture -import java.util.concurrent.CompletionException import java.util.concurrent.TimeUnit import kotlin.math.log import kotlin.time.Duration import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds -class TrackScheduler(private val guild: Guild, private val link: Link) { +class TrackScheduler(private val guild: Guild, val link: Link) { companion object { private val logger = LoggerFactory.getLogger(Companion::class.java) private val audioManager = RobertifyAudioManager + private var EVENTS_SUBSCRIBED = false } private val requesters = ArrayList() private var lastSentMsg: Message? = null val disconnectManager = GuildDisconnectManager(guild) - val unannouncedTracks = emptyList().toMutableList() - val player: Player - get() = link.player val queueHandler = QueueHandler() + val player: LavalinkPlayer? = link.getPlayer().block() var announcementChannel: GuildMessageChannel? = null - suspend fun queue(track: Track) { - when { - player.playingTrack != null -> queueHandler.add(track) - else -> player.playTrack(track) - } + private fun usePlayer(playerCallback: (LavalinkPlayer) -> Unit) { + link.getPlayer().subscribe(playerCallback) } - suspend fun queue(tracks: Collection) { - val mutableTracks = tracks.toMutableList() - if (player.playingTrack == null) - player.playTrack(mutableTracks.removeFirst()) - queueHandler.addAll(mutableTracks) + fun playTrack(track: Track) { + this.link.createOrUpdatePlayer().setTrack(track) + .subscribe { + logger.debug("Now playing ${it.track?.info?.title}") + } } - suspend fun addToBeginningOfQueue(track: Track) = run { - when { - player.playingTrack != null -> queueHandler.addToBeginning(track) - else -> player.playTrack(track) + + fun queue(track: Track) { + usePlayer { player -> + when { + player.track == null -> playTrack(track) + else -> queueHandler.add(track) + } } } - suspend fun addToBeginningOfQueue(tracks: Collection) { + fun queue(tracks: Collection) { val mutableTracks = tracks.toMutableList() - if (player.playingTrack == null) { - player.playTrack(mutableTracks.removeFirst()) + usePlayer { player -> + if (player.track == null) + playTrack(mutableTracks.removeFirst()) + queueHandler.addAll(mutableTracks) } + } - queueHandler.addToBeginning(mutableTracks) + fun addToBeginningOfQueue(track: Track) = run { + usePlayer { player -> + when { + player.track != null -> queueHandler.addToBeginning(track) + else -> link.createOrUpdatePlayer().setTrack(track) + } + } } - suspend fun stop() { - queueHandler.clear() + fun addToBeginningOfQueue(tracks: Collection) { + val mutableTracks = tracks.toMutableList() - if (player.playingTrack != null) - player.stopTrack() + usePlayer { player -> + if (player.track == null) + playTrack(mutableTracks.removeFirst()) + queueHandler.addToBeginning(mutableTracks) + } } - init { - player.events.onEach { event -> - when (event) { - is TrackStartEvent -> onTrackStart(event) - is TrackStuckEvent -> onTrackStuck(event) - is TrackExceptionEvent -> onTrackException(event) - is TrackEndEvent -> onTrackEnd(event) - } + fun stop() { + usePlayer { player -> + queueHandler.clear() + if (player.track != null) + player.stopTrack() } - .launchIn(player.coroutineScope) + } + + init { + logger.debug("Initializing a new TrackScheduler for ${guild.name}...") + + if (!EVENTS_SUBSCRIBED) { + logger.debug("Subscribing to scheduler events...") + val lavalink = Robertify.lavalink + lavalink.on().subscribe { event -> onTrackStart(event) } + lavalink.on().subscribe { event -> onTrackEnd(event) } + lavalink.on().subscribe { event -> onTrackStuck(event) } + lavalink.on().subscribe { event -> onTrackException(event) } + EVENTS_SUBSCRIBED = true + logger.debug("Subscribed to scheduler events") + } else logger.debug("Already subscribed scheduler to events") } @OptIn(ExperimentalSerializationApi::class) - private suspend fun onTrackStart(event: TrackStartEvent) { + private fun onTrackStart(event: TrackStartEvent) { val track = event.track logger.debug( @@ -176,62 +193,65 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { logger.debug("The channel is not the request channel") - val requesterUser = Robertify.shardManager.retrieveUserById(requester.id).await() - val defaultBackgroundImage = ThemesConfig( - guild - ).getTheme().nowPlayingBanner - - val img: InputStream - try { - img = NowPlayingImageBuilder( - artistName = track.author, - title = track.title, - albumImage = try { - track.artworkUrl ?: defaultBackgroundImage - } catch (e: MissingFieldException) { - defaultBackgroundImage - }, - requesterName = requesterUser.name, - requesterAvatar = requesterUser.avatarUrl - ).build() ?: throw NullPointerException("The generated image was null!") - } catch (ex: Exception) { - // Either building the image failed or the bot doesn't have enough - // permission to send images in a certain channel - if (ex is PermissionException || ex is ImageBuilderException || ex is NullPointerException) { - try { - sendNowPlayingEmbed(trackInfo, requesterMention).await() - } catch (ex: PermissionException) { + Robertify.shardManager.retrieveUserById(requester.id).queue { requesterUser -> + val defaultBackgroundImage = ThemesConfig( + guild + ).getTheme().nowPlayingBanner + + val img: InputStream + try { + img = runBlocking { + NowPlayingImageBuilder( + artistName = track.info.author, + title = track.info.title, + albumImage = try { + track.artworkUrl ?: defaultBackgroundImage + } catch (e: MissingFieldException) { + defaultBackgroundImage + }, + requesterName = requesterUser.name, + requesterAvatar = requesterUser.avatarUrl + ).build() ?: throw NullPointerException("The generated image was null!") + } + } catch (ex: Exception) { + // Either building the image failed or the bot doesn't have enough + // permission to send images in a certain channel + if (ex is PermissionException || ex is ImageBuilderException || ex is NullPointerException) { try { - sendNowPlayingString(track.info, requesterMention).await() - } catch (e: Exception) { - logger.warn("I was not able to send a now playing message at all in ${guild.name}") + sendNowPlayingEmbed(trackInfo, requesterMention) + } catch (ex: PermissionException) { + try { + sendNowPlayingString(track.info, requesterMention) + } catch (e: Exception) { + logger.warn("I was not able to send a now playing message at all in ${guild.name}") + } + } catch (ex: Exception) { + logger.error("Unexpected error", ex) } - } catch (ex: Exception) { + } else { logger.error("Unexpected error", ex) } - } else { - logger.error("Unexpected error", ex) + return@queue } - return - } - - val imgMessage = announcementChannel!!.sendFiles( - FileUpload.fromData( - img, - AbstractImageBuilder.RANDOM_FILE_NAME - ) - ).await() - lastSentMsg?.delete()?.queueAfter( - 3L, TimeUnit.SECONDS, null, - ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE) - ) + announcementChannel!!.sendFiles( + FileUpload.fromData( + img, + AbstractImageBuilder.RANDOM_FILE_NAME + ) + ).queue { imgMessage -> + lastSentMsg?.delete()?.queueAfter( + 3L, TimeUnit.SECONDS, null, + ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE) + ) - lastSentMsg = imgMessage + lastSentMsg = imgMessage + } + } } - private suspend fun onTrackEnd(event: TrackEndEvent) { - val reason = event.reason + private fun onTrackEnd(event: TrackEndEvent) { + val reason = event.endReason logger.debug( "Track ended.\n" + @@ -244,7 +264,7 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { if (trackToUse == null) { queueHandler.trackRepeating = false nextTrack(null) - } else player.playTrack(trackToUse.copy()) + } else playTrack(trackToUse.makeClone()) } else if (reason.mayStartNext) { if (trackToUse != null) queueHandler.pushPastTrack(trackToUse) @@ -255,12 +275,13 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { } } - private suspend fun onTrackException(event: TrackExceptionEvent) { + private fun onTrackException(event: TrackExceptionEvent) { val exception = event.exception; val track = event.track val handleMessageCleanup: (msg: Message) -> Unit = { msg -> - msg.delete().queueAfter(10, TimeUnit.SECONDS) + msg.delete().queueAfter(10.seconds) + lastSentMsg?.delete()?.queueAfter(10.seconds) } if (exception.message?.contains("matching track") == true) { @@ -297,10 +318,20 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { ).build() ) ?.queue(handleMessageCleanup) - } else logger.error("There was an exception with playing the track {}", exception.cause) + } else { + logger.error("There was an exception with playing the track {}", exception.cause) + announcementChannel?.sendMessageEmbeds( + RobertifyEmbedUtils.embedMessage( + guild, + TrackSchedulerMessages.TRACK_COULD_NOT_BE_PLAYED, + Pair("{title}", track.info.title), + Pair("{author}", track.info.author), + ).build() + )?.queue(handleMessageCleanup) + } } - private suspend fun onTrackStuck(event: TrackStuckEvent) { + private fun onTrackStuck(event: TrackStuckEvent) { if (!TogglesConfig(guild).getToggle(Toggle.ANNOUNCE_MESSAGES)) return @@ -321,7 +352,7 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { nextTrack(track) } - private suspend fun getNowPlayingEmbed(trackInfo: TrackInfo, requesterMention: String): MessageEmbed { + private fun getNowPlayingEmbed(trackInfo: TrackInfo, requesterMention: String): MessageEmbed { val localeManager = LocaleManager[guild] return RobertifyEmbedUtils.embedMessage( guild, "${ @@ -343,40 +374,39 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { ).build() } - private suspend fun sendNowPlayingEmbed(trackInfo: TrackInfo, requesterMention: String): Deferred = - coroutineScope { - val embed = getNowPlayingEmbed(trackInfo, requesterMention) - return@coroutineScope async { - val message = announcementChannel?.sendMessageEmbeds(embed)?.await() - lastSentMsg?.delete()?.queueAfter( - 3L, TimeUnit.SECONDS, null, - ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE) - ) - lastSentMsg = message - return@async message - } + private fun sendNowPlayingEmbed(trackInfo: TrackInfo, requesterMention: String): CompletableFuture? { + val embed = getNowPlayingEmbed(trackInfo, requesterMention) + val message = announcementChannel?.sendMessageEmbeds(embed)?.submit() + message?.thenAcceptAsync { msg -> + lastSentMsg = msg + lastSentMsg?.delete()?.queueAfter( + 3L, TimeUnit.SECONDS, null, + ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE) + ) } - private suspend fun sendNowPlayingString( + return message + } + + private fun sendNowPlayingString( audioTrackInfo: TrackInfo, requesterMention: String - ): Deferred = coroutineScope { + ): CompletableFuture? { val embed = getNowPlayingEmbed(audioTrackInfo, requesterMention) - return@coroutineScope async { - val message = announcementChannel?.sendMessage(embed.description ?: "") - ?.await() - + val message = announcementChannel?.sendMessage(embed.description ?: "") + ?.submit() + message?.thenAcceptAsync { msg -> + lastSentMsg = msg lastSentMsg?.delete()?.queueAfter( 3L, TimeUnit.SECONDS, null, ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE) ) - - lastSentMsg = message - return@async message } + + return message } - suspend fun nextTrack(lastTrack: Track?, skipped: Boolean = false, skippedAt: Long? = null) { + fun nextTrack(lastTrack: Track?, skipped: Boolean = false, skippedAt: Long? = null) { val playtime = PlaytimeCommand.playtime if (lastTrack != null) { if (!skipped) @@ -396,7 +426,7 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { if (nextTrack != null) { logger.debug("Retrieved {} and attempting to play", nextTrack.info.title) - player.playTrack(nextTrack) + playTrack(nextTrack) } else { if (lastTrack != null && AutoPlayConfig(guild).getStatus() @@ -422,13 +452,13 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { trackIds = pastSpotifyTracks ) } else { - player.stopTrack() + player?.stopTrack() disconnectManager.scheduleDisconnect() } } } - suspend fun disconnect(announceMsg: Boolean = true) { + fun disconnect(announceMsg: Boolean = true) { val channel = guild.selfMember.voiceState?.channel ?: return if (GuildConfig(guild).getTwentyFourSevenMode()) return @@ -452,7 +482,7 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { } } - suspend fun scheduleDisconnect(time: Duration = 5.minutes, announceMsg: Boolean = true) = + fun scheduleDisconnect(time: Duration = 5.minutes, announceMsg: Boolean = true) = disconnectManager.scheduleDisconnect(time, announceMsg) fun removeScheduledDisconnect() = @@ -469,7 +499,7 @@ class TrackScheduler(private val guild: Guild, private val link: Link) { fun clearRequesters() = requesters.clear() - suspend fun getRequesterAsMention(track: Track): String { + fun getRequesterAsMention(track: Track): String { val requester = findRequester(track.info.identifier) return if (requester != null) "<@${requester.id}>" diff --git a/src/main/kotlin/main/audiohandlers/loaders/AudioLoader.kt b/src/main/kotlin/main/audiohandlers/loaders/AudioLoader.kt index 88ea0313..731d04ae 100644 --- a/src/main/kotlin/main/audiohandlers/loaders/AudioLoader.kt +++ b/src/main/kotlin/main/audiohandlers/loaders/AudioLoader.kt @@ -1,46 +1,46 @@ package main.audiohandlers.loaders -import dev.arbjerg.lavalink.protocol.v4.Exception -import dev.arbjerg.lavalink.protocol.v4.LoadResult -import dev.arbjerg.lavalink.protocol.v4.Playlist -import dev.arbjerg.lavalink.protocol.v4.Track -import dev.schlaubi.lavakord.rest.loadItem +import dev.arbjerg.lavalink.client.protocol.* +import dev.arbjerg.lavalink.protocol.v4.PlaylistInfo import main.audiohandlers.GuildMusicManager import main.main.Robertify import net.dv8tion.jda.api.entities.Guild abstract class AudioLoader(guild: Guild) { - internal val link = Robertify.lavaKord.getLink(guild.id) + internal val link = Robertify.lavalink.getLink(guild.idLong) abstract val query: String abstract val musicManager: GuildMusicManager - open suspend fun loadItem() { - when (val result = link.loadItem(query)) { - is LoadResult.TrackLoaded -> { - onTrackLoad(result.data) + open fun loadItem() { + link.loadItem(query) + .subscribe itemLoad@{ item -> + when (item) { + is TrackLoaded -> { + onTrackLoad(item.track) + } + + is PlaylistLoaded -> { + onPlaylistLoad(item.tracks, item.info) + } + + is SearchResult -> { + onSearchResultLoad(item.tracks) + } + + is NoMatches -> { + onNoMatches() + } + + is LoadFailed -> { + onException(item.exception) + } + } } - - is LoadResult.PlaylistLoaded -> { - onPlaylistLoad(result.data) - } - - is LoadResult.SearchResult -> { - onSearchResultLoad(result.data.tracks) - } - - is LoadResult.NoMatches -> { - onNoMatches() - } - - is LoadResult.LoadFailed -> { - onException(result.data) - } - } } - abstract suspend fun onPlaylistLoad(playlist: Playlist) - abstract suspend fun onSearchResultLoad(results: List) - abstract suspend fun onTrackLoad(result: Track) - abstract suspend fun onNoMatches() - abstract suspend fun onException(exception: Exception) + abstract fun onPlaylistLoad(playlist: List, playlistInfo: PlaylistInfo) + abstract fun onSearchResultLoad(results: List) + abstract fun onTrackLoad(result: Track) + abstract fun onNoMatches() + abstract fun onException(exception: TrackException) } \ No newline at end of file diff --git a/src/main/kotlin/main/audiohandlers/loaders/AutoPlayLoader.kt b/src/main/kotlin/main/audiohandlers/loaders/AutoPlayLoader.kt index 322eb776..c2fe4b26 100644 --- a/src/main/kotlin/main/audiohandlers/loaders/AutoPlayLoader.kt +++ b/src/main/kotlin/main/audiohandlers/loaders/AutoPlayLoader.kt @@ -1,12 +1,11 @@ package main.audiohandlers.loaders -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException -import dev.arbjerg.lavalink.protocol.v4.Playlist -import dev.arbjerg.lavalink.protocol.v4.Track +import dev.arbjerg.lavalink.client.protocol.Track +import dev.arbjerg.lavalink.client.protocol.TrackException +import dev.arbjerg.lavalink.protocol.v4.PlaylistInfo import dev.minn.jda.ktx.util.SLF4J import main.audiohandlers.GuildMusicManager import main.audiohandlers.loaders.MainAudioLoader.Companion.queueThenDelete -import main.audiohandlers.utils.identifier import main.utils.RobertifyEmbedUtils import main.utils.json.requestchannel.RequestChannelConfig import main.utils.locale.LocaleManager @@ -29,7 +28,7 @@ class AutoPlayLoader( private val queueHandler = scheduler.queueHandler private val guild = musicManager.guild - override suspend fun onPlaylistLoad(playlist: Playlist) { + override fun onPlaylistLoad(playlist: List, playlistInfo: PlaylistInfo) { if (channel != null) { val localeManager = LocaleManager[guild] scheduler.announcementChannel = channel @@ -45,14 +44,14 @@ class AutoPlayLoader( } val self = guild.selfMember - val mutableTracks = playlist.tracks.toMutableList() + val mutableTracks = playlist.toMutableList() mutableTracks.forEach { track -> - scheduler.unannouncedTracks.add(track.identifier) + scheduler.unannouncedTracks.add(track.info.identifier) scheduler.addRequester(self.id, track.info.identifier) } - - scheduler.player.playTrack(mutableTracks.removeFirst()) + + scheduler.playTrack(mutableTracks.removeFirst()) queueHandler.addAll(mutableTracks) if (queueHandler.queueRepeating) { @@ -64,15 +63,15 @@ class AutoPlayLoader( RequestChannelConfig(guild).updateMessage() } - override suspend fun onSearchResultLoad(results: List) { + override fun onSearchResultLoad(results: List) { throw UnsupportedOperationException("This operation is not supported in the auto-play loader!") } - override suspend fun onTrackLoad(result: Track) { + override fun onTrackLoad(result: Track) { throw UnsupportedOperationException("This operation is not supported in the auto-play loader!") } - override suspend fun onNoMatches() { + override fun onNoMatches() { channel?.sendMessageEmbeds( RobertifyEmbedUtils.embedMessage( guild, @@ -84,7 +83,7 @@ class AutoPlayLoader( } } - override suspend fun onException(exception: dev.arbjerg.lavalink.protocol.v4.Exception) { + override fun onException(exception: TrackException) { channel?.sendMessageEmbeds( RobertifyEmbedUtils.embedMessage( guild, @@ -94,10 +93,8 @@ class AutoPlayLoader( ?.queueThenDelete(time = 5, unit = TimeUnit.MINUTES) { musicManager.scheduler.scheduleDisconnect(announceMsg = true) } - throw FriendlyException( + throw NullPointerException( "There were no similar tracks found!", - FriendlyException.Severity.COMMON, - NullPointerException() ) } } \ No newline at end of file diff --git a/src/main/kotlin/main/audiohandlers/loaders/MainAudioLoader.kt b/src/main/kotlin/main/audiohandlers/loaders/MainAudioLoader.kt index 3106a42c..8e3402a0 100644 --- a/src/main/kotlin/main/audiohandlers/loaders/MainAudioLoader.kt +++ b/src/main/kotlin/main/audiohandlers/loaders/MainAudioLoader.kt @@ -1,9 +1,9 @@ package main.audiohandlers.loaders import com.github.topi314.lavasrc.spotify.SpotifySourceManager -import dev.arbjerg.lavalink.protocol.v4.Exception -import dev.arbjerg.lavalink.protocol.v4.Playlist -import dev.arbjerg.lavalink.protocol.v4.Track +import dev.arbjerg.lavalink.client.protocol.Track +import dev.arbjerg.lavalink.client.protocol.TrackException +import dev.arbjerg.lavalink.protocol.v4.PlaylistInfo import dev.minn.jda.ktx.coroutines.await import dev.minn.jda.ktx.events.getDefaultScope import kotlinx.coroutines.runBlocking @@ -41,12 +41,12 @@ class MainAudioLoader( private val logger = LoggerFactory.getLogger(Companion::class.java) private val executorService = Executors.newSingleThreadScheduledExecutor() - suspend fun RestAction.queueThenDelete( + suspend fun RestAction.queueThenDeleteCoroutine( context: CoroutineContext = getDefaultScope().coroutineContext, time: Long = 10, unit: TimeUnit = TimeUnit.SECONDS, - deletePredicate: (suspend (message: Message) -> Boolean)? = null, - onSuccess: (suspend (message: Message) -> Unit)? = null + deletePredicate: ((message: Message) -> Boolean)? = null, + onSuccess: ((message: Message) -> Unit)? = null ) { val message = this.await(); if (deletePredicate == null || deletePredicate(message)) { @@ -58,6 +58,22 @@ class MainAudioLoader( }, time, unit) } } + + fun RestAction.queueThenDelete( + time: Long = 10, + unit: TimeUnit = TimeUnit.SECONDS, + deletePredicate: ((message: Message) -> Boolean)? = null, + onSuccess: ((message: Message) -> Unit)? = null + ) { + this.queue { message -> + if (deletePredicate == null || deletePredicate(message)) { + executorService.schedule({ + message.delete().queue() + onSuccess?.invoke(message) + }, time, unit) + } + } + } } private val guild = musicManager.guild @@ -67,7 +83,7 @@ class MainAudioLoader( _announcementChannel ?: botMsg?.channel?.asGuildMessageChannel() private val requestChannelConfig = RequestChannelConfig(guild) - private suspend fun handleMessageUpdate(embed: MessageEmbed) { + private fun handleMessageUpdate(embed: MessageEmbed) { if (botMsg != null) botMsg.editMessageEmbeds(embed) .queueThenDelete( @@ -82,7 +98,7 @@ class MainAudioLoader( } } - private suspend fun sendTrackLoadedMessage(track: Track) { + private fun sendTrackLoadedMessage(track: Track) { val embed = RobertifyEmbedUtils.embedMessage( guild, AudioLoaderMessages.QUEUE_ADD, @@ -93,12 +109,12 @@ class MainAudioLoader( handleMessageUpdate(embed) } - override suspend fun onPlaylistLoad(playlist: Playlist) { - val mutableTracks = playlist.tracks.toMutableList() + override fun onPlaylistLoad(playlist: List, playlistInfo: PlaylistInfo) { + val mutableTracks = playlist.toMutableList() val embed = RobertifyEmbedUtils.embedMessage( guild, AudioLoaderMessages.QUEUE_PLAYLIST_ADD, Pair("{numTracks}", mutableTracks.size.toString()), - Pair("{playlist}", playlist.info.name) + Pair("{playlist}", playlistInfo.name) ).build() handleMessageUpdate(embed) @@ -119,7 +135,7 @@ class MainAudioLoader( LogType.QUEUE_ADD, AudioLoaderMessages.QUEUE_PLAYLIST_ADD, Pair("{user}", sender.asMention), Pair("{numTracks}", mutableTracks.size.toString()), - Pair("{playlist}", playlist.info.name) + Pair("{playlist}", playlistInfo.name) ) } @@ -129,7 +145,7 @@ class MainAudioLoader( scheduler.queue(mutableTracks) } - override suspend fun onSearchResultLoad(results: List) { + override fun onSearchResultLoad(results: List) { val firstResult = results.first() val trackInfo = firstResult.info @@ -156,7 +172,7 @@ class MainAudioLoader( ) } - override suspend fun onTrackLoad(result: Track) { + override fun onTrackLoad(result: Track) { sendTrackLoadedMessage(result) val trackInfo = result.info @@ -188,7 +204,7 @@ class MainAudioLoader( requestChannelConfig.updateMessage() } - override suspend fun onNoMatches() { + override fun onNoMatches() { val embed = if (query.length < 4096) RobertifyEmbedUtils.embedMessage( guild, @@ -201,25 +217,29 @@ class MainAudioLoader( handleMessageUpdate(embed) - if (queueHandler.isEmpty && musicManager.player.playingTrack == null) - scheduler.scheduleDisconnect(1.seconds, false) + musicManager.usePlayer { player -> + if (queueHandler.isEmpty && player?.track== null) + scheduler.scheduleDisconnect(1.seconds, false) + } } - override suspend fun onException(exception: Exception) { - if (musicManager.player.playingTrack == null) - musicManager.leave() + override fun onException(exception: TrackException) { + musicManager.usePlayer { player -> + if (player.track == null) + musicManager.leave() - if (exception.message?.contains("available") != true && exception.message?.contains("format") != true) - logger.error("Could not load tracks in ${guild.name}!", exception) + if (exception.message?.contains("available") != true && exception.message?.contains("format") != true) + logger.error("Could not load tracks in ${guild.name}!", exception) - val embed = RobertifyEmbedUtils.embedMessage( - guild, - if (exception.message?.contains("available") == true || exception.message?.contains("format") == true) - exception.message!! - else LocaleManager[guild] - .getMessage(AudioLoaderMessages.ERROR_LOADING_TRACK) - ).build() + val embed = RobertifyEmbedUtils.embedMessage( + guild, + if (exception.message?.contains("available") == true || exception.message?.contains("format") == true) + exception.message!! + else LocaleManager[guild] + .getMessage(AudioLoaderMessages.ERROR_LOADING_TRACK) + ).build() - handleMessageUpdate(embed) + handleMessageUpdate(embed) + } } } \ No newline at end of file diff --git a/src/main/kotlin/main/audiohandlers/loaders/SearchResultLoader.kt b/src/main/kotlin/main/audiohandlers/loaders/SearchResultLoader.kt index ebecf778..fff2d093 100644 --- a/src/main/kotlin/main/audiohandlers/loaders/SearchResultLoader.kt +++ b/src/main/kotlin/main/audiohandlers/loaders/SearchResultLoader.kt @@ -1,9 +1,9 @@ package main.audiohandlers.loaders import com.github.topi314.lavasrc.spotify.SpotifySourceManager -import dev.arbjerg.lavalink.protocol.v4.Exception -import dev.arbjerg.lavalink.protocol.v4.Playlist -import dev.arbjerg.lavalink.protocol.v4.Track +import dev.arbjerg.lavalink.client.protocol.Track +import dev.arbjerg.lavalink.client.protocol.TrackException +import dev.arbjerg.lavalink.protocol.v4.PlaylistInfo import dev.minn.jda.ktx.interactions.components.danger import dev.minn.jda.ktx.messages.send import main.audiohandlers.GuildMusicManager @@ -28,11 +28,11 @@ class SearchResultLoader( ) : AudioLoader(musicManager.guild) { private val guild = musicManager.guild - override suspend fun onPlaylistLoad(playlist: Playlist) { + override fun onPlaylistLoad(playlist: List, playlistInfo: PlaylistInfo) { throw UnsupportedOperationException("This operation is not supported in the search result loader") } - override suspend fun onSearchResultLoad(results: List) { + override fun onSearchResultLoad(results: List) { val localeManager = LocaleManager[guild] val embedDesc = StringBuilder() @@ -83,11 +83,11 @@ class SearchResultLoader( ).queue() } - override suspend fun onTrackLoad(result: Track) { + override fun onTrackLoad(result: Track) { throw UnsupportedOperationException("This operation is not supported in the search result loader") } - override suspend fun onNoMatches() { + override fun onNoMatches() { botMessage.editOriginalEmbeds( RobertifyEmbedUtils.embedMessage( guild, @@ -98,7 +98,7 @@ class SearchResultLoader( .queue() } - override suspend fun onException(exception: Exception) { + override fun onException(exception: TrackException) { TODO("Not yet implemented") } } \ No newline at end of file diff --git a/src/main/kotlin/main/audiohandlers/models/Requester.kt b/src/main/kotlin/main/audiohandlers/models/Requester.kt index 86b02b88..fec18253 100644 --- a/src/main/kotlin/main/audiohandlers/models/Requester.kt +++ b/src/main/kotlin/main/audiohandlers/models/Requester.kt @@ -6,7 +6,7 @@ import main.utils.GeneralUtils @Serializable data class Requester(val id: String, val trackId: String) { - suspend fun toMention(): String = GeneralUtils.toMention( + fun toMention(): String = GeneralUtils.toMention( id = id, mentioner = GeneralUtils.Mentioner.USER ) diff --git a/src/main/kotlin/main/audiohandlers/utils/AudioTrackExtentions.kt b/src/main/kotlin/main/audiohandlers/utils/AudioTrackExtentions.kt index 563a9027..d7842fae 100644 --- a/src/main/kotlin/main/audiohandlers/utils/AudioTrackExtentions.kt +++ b/src/main/kotlin/main/audiohandlers/utils/AudioTrackExtentions.kt @@ -1,7 +1,6 @@ package main.audiohandlers.utils -import dev.arbjerg.lavalink.protocol.v4.Track -import dev.schlaubi.lavakord.plugins.lavasrc.lavaSrcInfo +import dev.arbjerg.lavalink.client.protocol.Track import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.MissingFieldException @@ -28,7 +27,11 @@ val Track.source: String @OptIn(ExperimentalSerializationApi::class) val Track.artworkUrl: String? - get() = try { info.artworkUrl ?: lavaSrcInfo.artistArtworkUrl } catch (e: MissingFieldException) { null } + get() = try { + info.artworkUrl + } catch (e: MissingFieldException) { + null + } val Track.isrc: String? get() = info.isrc \ No newline at end of file diff --git a/src/main/kotlin/main/commands/slashcommands/SlashCommandManager.kt b/src/main/kotlin/main/commands/slashcommands/SlashCommandManager.kt index 8f7eada1..8e6d7b1a 100644 --- a/src/main/kotlin/main/commands/slashcommands/SlashCommandManager.kt +++ b/src/main/kotlin/main/commands/slashcommands/SlashCommandManager.kt @@ -122,10 +122,10 @@ object SlashCommandManager { fun ModalInteractionEvent.getRequiredValue(id: String): ModalMapping = this.getValue(id) ?: throw NullPointerException("Invalid value \"$id\". Are you sure that value is required?") - fun ShardManager.registerCommand(command: AbstractSlashCommand) = + suspend fun ShardManager.registerCommand(command: AbstractSlashCommand) = command.register(this) - fun ShardManager.registerCommands(commands: List) = + suspend fun ShardManager.registerCommands(commands: List) = commands.forEach { it.register(this) } val globalCommands: List diff --git a/src/main/kotlin/main/commands/slashcommands/audio/AutoPlayCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/AutoPlayCommand.kt index 6a138111..dc7f442f 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/AutoPlayCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/AutoPlayCommand.kt @@ -25,7 +25,7 @@ class AutoPlayCommand : AbstractSlashCommand( .queue() } - private suspend fun handleAutoPlay(guild: Guild): MessageEmbed { + private fun handleAutoPlay(guild: Guild): MessageEmbed { val localeManager = LocaleManager[guild] val autoPlayConfig = AutoPlayConfig(guild) diff --git a/src/main/kotlin/main/commands/slashcommands/audio/DisconnectCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/DisconnectCommand.kt index 066bcf89..852b0e9f 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/DisconnectCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/DisconnectCommand.kt @@ -25,7 +25,7 @@ class DisconnectCommand : AbstractSlashCommand( }.queue() } - suspend fun handleDisconnect(selfVoiceState: GuildVoiceState, memberVoiceState: GuildVoiceState): MessageEmbed { + fun handleDisconnect(selfVoiceState: GuildVoiceState, memberVoiceState: GuildVoiceState): MessageEmbed { val guild = selfVoiceState.guild val acChecks = audioChannelChecks(memberVoiceState, selfVoiceState, selfChannelNeeded = true) if (acChecks != null) return acChecks diff --git a/src/main/kotlin/main/commands/slashcommands/audio/FavouriteTracksCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/FavouriteTracksCommand.kt index 38e82cf6..e88f154b 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/FavouriteTracksCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/FavouriteTracksCommand.kt @@ -187,17 +187,18 @@ class FavouriteTracksCommand : AbstractSlashCommand( } } - suspend fun handleAdd(guild: Guild, member: Member): MessageEmbed { - val config = FavouriteTracksCache.instance - val musicManager = RobertifyAudioManager[guild] - val player = musicManager.player - val playingTrack = player.playingTrack + fun handleAdd(guild: Guild, member: Member): MessageEmbed { val memberVoiceState = member.voiceState!! val selfVoiceState = guild.selfMember.voiceState!! val acChecks = audioChannelChecks(memberVoiceState, selfVoiceState) if (acChecks != null) return acChecks + val config = FavouriteTracksCache.instance + val musicManager = RobertifyAudioManager[guild] + val player = musicManager.player!! + val playingTrack = player.track + val id = playingTrack!!.info.identifier logger.debug("source: ${playingTrack.source}") diff --git a/src/main/kotlin/main/commands/slashcommands/audio/JumpCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/JumpCommand.kt index 29d30ada..e156eb76 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/JumpCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/JumpCommand.kt @@ -1,8 +1,7 @@ package main.commands.slashcommands.audio -import com.sedmelluq.discord.lavaplayer.track.AudioTrack -import dev.arbjerg.lavalink.protocol.v4.Track -import dev.schlaubi.lavakord.audio.player.Player +import dev.arbjerg.lavalink.client.LavalinkPlayer +import dev.arbjerg.lavalink.client.protocol.Track import main.audiohandlers.RobertifyAudioManager import main.audiohandlers.utils.length import main.commands.slashcommands.SlashCommandManager.getRequiredOption @@ -10,8 +9,8 @@ import main.utils.GeneralUtils.isInt import main.utils.RobertifyEmbedUtils import main.utils.RobertifyEmbedUtils.Companion.sendEmbed import main.utils.component.interactions.slashcommand.AbstractSlashCommand -import main.utils.component.interactions.slashcommand.models.SlashCommand import main.utils.component.interactions.slashcommand.models.CommandOption +import main.utils.component.interactions.slashcommand.models.SlashCommand import main.utils.json.logs.LogType import main.utils.json.logs.LogUtilsKt import main.utils.locale.messages.GeneralMessages @@ -66,8 +65,8 @@ class JumpCommand : AbstractSlashCommand( val guild = selfVoiceState.guild val musicManager = RobertifyAudioManager[guild] - val player = musicManager.player - val track = player.playingTrack + val player = musicManager.player!! + val track = player.track ?: return RobertifyEmbedUtils.embedMessage( guild, GeneralMessages.NOTHING_PLAYING @@ -86,7 +85,7 @@ class JumpCommand : AbstractSlashCommand( guild: Guild, jumper: User, input: String, - player: Player, + player: LavalinkPlayer, track: Track ): MessageEmbed { var time = if (input.isInt()) @@ -112,7 +111,7 @@ class JumpCommand : AbstractSlashCommand( JumpMessages.JUMP_DURATION_GT_TIME_LEFT ).build() - player.seekTo(player.position + time) + player.setPosition(player.position + time) LogUtilsKt(guild).sendLog( LogType.TRACK_JUMP, JumpMessages.JUMPED_LOG, diff --git a/src/main/kotlin/main/commands/slashcommands/audio/LoopCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/LoopCommand.kt index 3425e333..8f6fbd2e 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/LoopCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/LoopCommand.kt @@ -1,6 +1,6 @@ package main.commands.slashcommands.audio -import dev.schlaubi.lavakord.audio.player.Player +import dev.arbjerg.lavalink.client.LavalinkPlayer import main.audiohandlers.GuildMusicManager import main.audiohandlers.RobertifyAudioManager import main.audiohandlers.utils.author @@ -57,14 +57,14 @@ class LoopCommand : AbstractSlashCommand( private suspend fun checks( selfVoiceState: GuildVoiceState, memberVoiceState: GuildVoiceState, - player: Player + player: LavalinkPlayer? ): MessageEmbed? { val acChecks = audioChannelChecks(memberVoiceState, selfVoiceState) if (acChecks != null) return acChecks val guild = memberVoiceState.guild - if (player.playingTrack == null) + if (player?.track== null) return RobertifyEmbedUtils.embedMessage(guild, LoopMessages.LOOP_NOTHING_PLAYING) .build() @@ -76,7 +76,7 @@ class LoopCommand : AbstractSlashCommand( val player = musicManager.player val scheduler = musicManager.scheduler val queueHandler = scheduler.queueHandler - val track = player.playingTrack + val track = player?.track ?: return RobertifyEmbedUtils.embedMessage( guild, GeneralMessages.NOTHING_PLAYING @@ -87,14 +87,14 @@ class LoopCommand : AbstractSlashCommand( RobertifyEmbedUtils.embedMessage( guild, LoopMessages.LOOP_STOP, - Pair("{title}", track.title) + Pair("{title}", track.info.title) ).build() } else { queueHandler.trackRepeating = true RobertifyEmbedUtils.embedMessage( guild, LoopMessages.LOOP_START, - Pair("{title}", track.title) + Pair("{title}", track.info.title) ).build() } @@ -103,8 +103,8 @@ class LoopCommand : AbstractSlashCommand( LoopMessages.LOOP_STOP, Pair("{user}", looper.asMention), Pair("{status}", if (queueHandler.trackRepeating) "looped" else "unlooped"), - Pair("{title}", track.title), - Pair("{author}", track.author) + Pair("{title}", track.info.title), + Pair("{author}", track.info.author) ) return embed @@ -120,11 +120,11 @@ class LoopCommand : AbstractSlashCommand( queueHandler.clearSavedQueue() RobertifyEmbedUtils.embedMessage(guild, LoopMessages.QUEUE_LOOP_STOP).build() } else { - if (player.playingTrack == null) { + if (player?.track== null) { RobertifyEmbedUtils.embedMessage(guild, GeneralMessages.NOTHING_PLAYING) .build() } else { - val thisTrack = player.playingTrack!! + val thisTrack = player.track!! if (queueHandler.isEmpty) RobertifyEmbedUtils.embedMessage(guild, LoopMessages.QUEUE_LOOP_NOTHING) .build() diff --git a/src/main/kotlin/main/commands/slashcommands/audio/LyricsCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/LyricsCommand.kt index 29de9d95..a6e6facc 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/LyricsCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/LyricsCommand.kt @@ -57,8 +57,8 @@ class LyricsCommand : AbstractSlashCommand( } val playingTrack = RobertifyAudioManager[guild] - .player - .playingTrack!! + .player!! + .track!! "${playingTrack.title} by ${playingTrack.author}" } diff --git a/src/main/kotlin/main/commands/slashcommands/audio/NowPlayingCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/NowPlayingCommand.kt index 9ff16549..8c0ca10f 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/NowPlayingCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/NowPlayingCommand.kt @@ -1,5 +1,6 @@ package main.commands.slashcommands.audio +import dev.arbjerg.lavalink.protocol.v4.ifPresent import dev.minn.jda.ktx.util.SLF4J import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.MissingFieldException @@ -43,19 +44,23 @@ class NowPlayingCommand : AbstractSlashCommand( override suspend fun handle(event: SlashCommandInteractionEvent) { event.deferReply().queue() - val guild = event.guild!! val memberVoiceState = event.member!!.voiceState!! val selfVoiceState = guild.selfMember.voiceState!! - val acChecks = audioChannelChecks(memberVoiceState, selfVoiceState, true, true) + val acChecks = audioChannelChecks( + memberVoiceState, + selfVoiceState, + selfChannelNeeded = true, + songMustBePlaying = true, + ) if (acChecks != null) { - event.replyEmbed { acChecks }.setEphemeral(true).queue() + event.hook.sendEmbed { acChecks }.queue() return } val musicManager = RobertifyAudioManager[guild] val player = musicManager.player - val track = player.playingTrack + val track = player?.track val sendBackupEmbed: suspend () -> Unit = { event.hook.sendEmbed(guild) { @@ -67,7 +72,7 @@ class NowPlayingCommand : AbstractSlashCommand( val defaultImage = ThemesConfig(guild).getTheme().nowPlayingBanner val builder = NowPlayingImageBuilder( title = track!!.title, - artistName = track.author, + artistName = track.info.author, albumImage = try { track.artworkUrl ?: defaultImage } catch (e: MissingFieldException) { @@ -99,7 +104,7 @@ class NowPlayingCommand : AbstractSlashCommand( } } - private suspend fun getNowPlayingEmbed( + private fun getNowPlayingEmbed( guild: Guild, channel: GuildMessageChannel, selfVoiceState: GuildVoiceState, @@ -107,7 +112,7 @@ class NowPlayingCommand : AbstractSlashCommand( ): MessageEmbed { val musicManager = RobertifyAudioManager[guild] val player = musicManager.player - val track = player.playingTrack + val track = player?.track val embed: MessageEmbed? = when { !selfVoiceState.inAudioChannel() -> RobertifyEmbedUtils.embedMessage( @@ -138,15 +143,15 @@ class NowPlayingCommand : AbstractSlashCommand( if (embed != null) return embed - val progress = player.position.toDouble() / track!!.length - val filters = player.filters - val requester = musicManager.scheduler.findRequester(track.identifier) + val progress = player?.position?.toDouble()?.div(track!!.length) + val filters = player?.filters + val requester = musicManager.scheduler.findRequester(track!!.identifier) val localeManager = LocaleManager[guild] val embedBuilder = RobertifyEmbedUtils.embedMessageWithTitle( guild, localeManager.getMessage( NowPlayingMessages.NP_EMBED_TITLE, - Pair("{title}", track.title), - Pair("{author}", track.author) + Pair("{title}", track.info.title), + Pair("{author}", track.info.author) ), "${ if (TogglesConfig(guild).getToggle(Toggle.SHOW_REQUESTER) && requester != null) { @@ -164,7 +169,7 @@ class NowPlayingCommand : AbstractSlashCommand( GeneralUtils.progressBar( guild, channel, - progress, + progress ?: 0.0, GeneralUtils.ProgressBar.DURATION ) }" + @@ -182,7 +187,7 @@ class NowPlayingCommand : AbstractSlashCommand( GeneralUtils.progressBar( guild, channel, - filters.volume?.toDouble() ?: 0.0, + filters?.volume?.ifPresent { it.toDouble() } ?: 0.0, GeneralUtils.ProgressBar.FILL ) } 🔊" diff --git a/src/main/kotlin/main/commands/slashcommands/audio/PauseCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/PauseCommand.kt index 6dca31ca..c1096b69 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/PauseCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/PauseCommand.kt @@ -31,11 +31,11 @@ class PauseCommand : AbstractSlashCommand( val guild = selfVoiceState.guild val musicManager = RobertifyAudioManager[guild] - val player = musicManager.player + val player = musicManager.player!! val logUtils = LogUtilsKt(guild) return if (player.paused) { - player.pause(false) + player.setPaused(false) musicManager.isForcePaused = false logUtils.sendLog( LogType.PLAYER_RESUME, @@ -44,7 +44,7 @@ class PauseCommand : AbstractSlashCommand( ) RobertifyEmbedUtils.embedMessage(guild, PauseMessages.RESUMED).build() } else { - player.pause(true) + player.setPaused(true) musicManager.isForcePaused = true logUtils.sendLog( LogType.PLAYER_PAUSE, diff --git a/src/main/kotlin/main/commands/slashcommands/audio/PlayCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/PlayCommand.kt index 97485d53..013ff430 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/PlayCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/PlayCommand.kt @@ -29,6 +29,7 @@ import net.dv8tion.jda.api.interactions.commands.Command.Choice import net.dv8tion.jda.api.interactions.commands.OptionType import org.slf4j.LoggerFactory import java.io.File +import java.net.URI import java.net.URL import java.nio.file.Files import java.nio.file.Paths @@ -141,7 +142,7 @@ class PlayCommand : AbstractSlashCommand( event.hook.sendEmbed(guild) { embed(ShufflePlayMessages.INVALID_LINK) } - } else link = URL(link).getDestination() + } else link = URI(link).toURL().getDestination() when { link.contains("spotify") && !link.matches("(https?://)?(www\\.)?open\\.spotify\\.com/(user/[a-zA-Z0-9-_]+/)?(?album|playlist|artist)/(?[a-zA-Z0-9-_]+)(\\?si=.+)?".toRegex()) -> { @@ -198,7 +199,7 @@ class PlayCommand : AbstractSlashCommand( override val help: String get() = "Plays a song" - private suspend fun handlePlayTracks( + private fun handlePlayTracks( event: SlashCommandInteractionEvent, link: String, addToBeginning: Boolean = false, @@ -220,19 +221,15 @@ class PlayCommand : AbstractSlashCommand( event.hook.sendEmbed(guild) { embed(FavouriteTracksMessages.FT_ADDING_TO_QUEUE_2) - }.queueCoroutine { msg -> - coroutineScope { - launch { - RobertifyAudioManager - .loadAndPlay( - trackUrl = link, - memberVoiceState = member.voiceState!!, - botMessage = msg, - addToBeginning = addToBeginning, - shuffled = shuffled - ) - } - } + }.queue { msg -> + RobertifyAudioManager + .loadAndPlay( + trackUrl = link, + memberVoiceState = member.voiceState!!, + botMessage = msg, + addToBeginning = addToBeginning, + shuffled = shuffled + ) } } diff --git a/src/main/kotlin/main/commands/slashcommands/audio/PreviousTrackCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/PreviousTrackCommand.kt index 1edd9d85..491ab8d7 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/PreviousTrackCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/PreviousTrackCommand.kt @@ -34,7 +34,7 @@ class PreviousTrackCommand : AbstractSlashCommand( val musicManager = RobertifyAudioManager[guild] val scheduler = musicManager.scheduler val queueHandler = scheduler.queueHandler - val player = musicManager.player + val player = musicManager.player!! if (queueHandler.isPreviousTracksEmpty) return RobertifyEmbedUtils.embedMessage( @@ -42,10 +42,10 @@ class PreviousTrackCommand : AbstractSlashCommand( PreviousTrackMessages.NO_PREV_TRACKS ).build() - val currentTrack = player.playingTrack!! + val currentTrack = player.track!! queueHandler.addToBeginning(currentTrack) player.stopTrack() - player.playTrack(queueHandler.popPreviousTrack()!!) + scheduler.playTrack(queueHandler.popPreviousTrack()!!) RequestChannelConfig(guild).updateMessage() diff --git a/src/main/kotlin/main/commands/slashcommands/audio/QueueCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/QueueCommand.kt index 733a8344..6ba59cef 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/QueueCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/QueueCommand.kt @@ -45,8 +45,8 @@ class QueueCommand : AbstractSlashCommand( trackList.forEachIndexed { i, track -> content.add(localeManager.getMessage(QueueMessages.QUEUE_ENTRY, Pair("{id}", (i + 1).toString()), - Pair("{title}", track.title), - Pair("{author}", track.author), + Pair("{title}", track.info.title), + Pair("{author}", track.info.author), Pair("{duration}", GeneralUtils.formatTime(track.length)) )) } @@ -75,8 +75,8 @@ class QueueCommand : AbstractSlashCommand( trackList.forEachIndexed { i, track -> content.add(localeManager.getMessage(QueueMessages.QUEUE_ENTRY, Pair("{id}", (i + 1).toString()), - Pair("{title}", track.title), - Pair("{author}", track.author), + Pair("{title}", track.info.title), + Pair("{author}", track.info.author), Pair("{duration}", GeneralUtils.formatTime(track.length)) )) } diff --git a/src/main/kotlin/main/commands/slashcommands/audio/RemoveCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/RemoveCommand.kt index c2e37a78..3a402b8d 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/RemoveCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/RemoveCommand.kt @@ -73,7 +73,7 @@ class RemoveCommand : AbstractSlashCommand( } } - private suspend fun handleRemove( + private fun handleRemove( memberVoiceState: GuildVoiceState, selfVoiceState: GuildVoiceState, id: Int @@ -125,7 +125,7 @@ class RemoveCommand : AbstractSlashCommand( } } - private suspend fun handleRemove( + private fun handleRemove( memberVoiceState: GuildVoiceState, selfVoiceState: GuildVoiceState, name: String diff --git a/src/main/kotlin/main/commands/slashcommands/audio/ResumeCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/ResumeCommand.kt index 6cf1fe55..22c721b3 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/ResumeCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/ResumeCommand.kt @@ -23,17 +23,17 @@ class ResumeCommand : AbstractSlashCommand(SlashCommand( event.replyEmbed { handleResume(memberVoiceState, selfVoiceState) }.queue() } - private suspend fun handleResume(memberVoiceState: GuildVoiceState, selfVoiceState: GuildVoiceState): MessageEmbed { + private fun handleResume(memberVoiceState: GuildVoiceState, selfVoiceState: GuildVoiceState): MessageEmbed { val acChecks = audioChannelChecks(memberVoiceState, selfVoiceState, songMustBePlaying = true) if (acChecks != null) return acChecks val guild = selfVoiceState.guild val player = RobertifyAudioManager[guild] - .player + .player!! if (!player.paused) return RobertifyEmbedUtils.embedMessage(guild, PauseMessages.PLAYER_NOT_PAUSED).build() - player.pause(false) + player.setPaused(false) LogUtilsKt(guild).sendLog( LogType.PLAYER_RESUME, PauseMessages.RESUMED_LOG, diff --git a/src/main/kotlin/main/commands/slashcommands/audio/RewindCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/RewindCommand.kt index c2bcd97a..98153597 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/RewindCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/RewindCommand.kt @@ -55,8 +55,8 @@ class RewindCommand : AbstractSlashCommand( val acChecks = audioChannelChecks(memberVoiceState, selfVoiceState, songMustBePlaying = true) if (acChecks != null) return acChecks - val player = RobertifyAudioManager[guild].player - val playingTrack = player.playingTrack!! + val player = RobertifyAudioManager[guild].player!! + val playingTrack = player.track!! if (playingTrack.isStream) return RobertifyEmbedUtils.embedMessage(guild, RewindMessages.CANT_REWIND_STREAM) @@ -65,7 +65,7 @@ class RewindCommand : AbstractSlashCommand( val logUtils = LogUtilsKt(guild) return if (time == null) { - player.seekTo(0) + player.setPosition(0) logUtils.sendLog( LogType.TRACK_REWIND, RewindMessages.REWIND_TO_BEGINNING_LOG, @@ -90,7 +90,7 @@ class RewindCommand : AbstractSlashCommand( RewindMessages.DURATION_GT_CURRENT_TIME ).build() - player.seekTo(player.position - timeInMillis) + player.setPosition(player.position - timeInMillis) logUtils.sendLog( LogType.TRACK_REWIND, RewindMessages.REWOUND_BY_DURATION_LOG, diff --git a/src/main/kotlin/main/commands/slashcommands/audio/SearchCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/SearchCommand.kt index dbc1291a..4654607f 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/SearchCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/SearchCommand.kt @@ -49,7 +49,7 @@ class SearchCommand : AbstractSlashCommand( SearchMessages.LOOKING_FOR, Pair("{query}", query) ) - }.queueCoroutine { addingMsg -> + }.queue { addingMsg -> getSearchResult( guild, event.user, @@ -59,7 +59,7 @@ class SearchCommand : AbstractSlashCommand( } } - private suspend fun getSearchResult( + private fun getSearchResult( guild: Guild, requester: User, botMSg: InteractionHook, diff --git a/src/main/kotlin/main/commands/slashcommands/audio/SeekCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/SeekCommand.kt index ce120874..a3f834e2 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/SeekCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/SeekCommand.kt @@ -82,14 +82,14 @@ class SeekCommand : AbstractSlashCommand( DurationUnit.SECONDS ).inWholeMilliseconds - val player = RobertifyAudioManager[guild].player - val playingTrack = player.playingTrack!! + val player = RobertifyAudioManager[guild].player!! + val playingTrack = player.track!! if (seekDuration > playingTrack.length) return RobertifyEmbedUtils.embedMessage(guild, SeekMessages.POS_GT_DURATION) .build() - player.seekTo(seekDuration) + player.setPosition(seekDuration) val time = "${if (hours > 9) "$hours" else "0$hours"}:${if (minutes > 9) "$minutes" else "0$minutes"}:${if (seconds > 9) "$seconds" else "0$seconds"}" diff --git a/src/main/kotlin/main/commands/slashcommands/audio/ShuffleCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/ShuffleCommand.kt index b7a83bea..a06eed1e 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/ShuffleCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/ShuffleCommand.kt @@ -29,7 +29,7 @@ class ShuffleCommand : AbstractSlashCommand( }.queue() } - suspend fun handleShuffle(guild: Guild, shuffler: User): MessageEmbed { + fun handleShuffle(guild: Guild, shuffler: User): MessageEmbed { val musicManager = RobertifyAudioManager[guild] val queueHandler = musicManager.scheduler.queueHandler diff --git a/src/main/kotlin/main/commands/slashcommands/audio/SkipCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/SkipCommand.kt index 5e2f6842..2493a5f1 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/SkipCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/SkipCommand.kt @@ -4,12 +4,8 @@ import dev.minn.jda.ktx.coroutines.await import dev.minn.jda.ktx.interactions.components.danger import dev.minn.jda.ktx.interactions.components.success import dev.minn.jda.ktx.util.SLF4J -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import main.audiohandlers.GuildMusicManager import main.audiohandlers.RobertifyAudioManager -import main.audiohandlers.utils.author -import main.audiohandlers.utils.title import main.commands.slashcommands.SlashCommandManager.getRequiredOption import main.constants.RobertifyPermission import main.utils.GeneralUtils @@ -18,8 +14,8 @@ import main.utils.RobertifyEmbedUtils.Companion.editEmbed import main.utils.RobertifyEmbedUtils.Companion.replyEmbed import main.utils.RobertifyEmbedUtils.Companion.sendEmbed import main.utils.component.interactions.slashcommand.AbstractSlashCommand -import main.utils.component.interactions.slashcommand.models.SlashCommand import main.utils.component.interactions.slashcommand.models.CommandOption +import main.utils.component.interactions.slashcommand.models.SlashCommand import main.utils.json.logs.LogType import main.utils.json.logs.LogUtilsKt import main.utils.json.requestchannel.RequestChannelConfig @@ -95,7 +91,7 @@ class SkipCommand : AbstractSlashCommand( } } - suspend fun handleSkip(selfVoiceState: GuildVoiceState, memberVoiceState: GuildVoiceState): MessageEmbed { + fun handleSkip(selfVoiceState: GuildVoiceState, memberVoiceState: GuildVoiceState): MessageEmbed { val guild = selfVoiceState.guild val checksEmbed = audioChannelChecks(selfVoiceState, memberVoiceState, songMustBePlaying = true) @@ -105,7 +101,7 @@ class SkipCommand : AbstractSlashCommand( val musicManager = RobertifyAudioManager[guild] val player = musicManager.player - if (player.playingTrack == null) + if (player?.track == null) return RobertifyEmbedUtils.embedMessage(guild, SkipMessages.NOTHING_TO_SKIP) .build() @@ -118,7 +114,7 @@ class SkipCommand : AbstractSlashCommand( return RobertifyEmbedUtils.embedMessage(guild, SkipMessages.SKIPPED).build() } - suspend fun handleSkip(skipper: User, musicManager: GuildMusicManager, id: Int): MessageEmbed { + fun handleSkip(skipper: User, musicManager: GuildMusicManager, id: Int): MessageEmbed { val scheduler = musicManager.scheduler val queueHandler = scheduler.queueHandler @@ -129,7 +125,7 @@ class SkipCommand : AbstractSlashCommand( ).build() val player = musicManager.player - val playingTrack = player.playingTrack!! + val playingTrack = player!!.track!! val guild = musicManager.guild val currentQueue = queueHandler.contents.toMutableList() val songsToRemove = currentQueue.subList(0, id - 1) @@ -143,7 +139,7 @@ class SkipCommand : AbstractSlashCommand( return RobertifyEmbedUtils.embedMessage(musicManager.guild, "Skipped to **track #$id**!").build() } - suspend fun handleVoteSkip( + fun handleVoteSkip( channel: GuildMessageChannel, selfVoiceState: GuildVoiceState, memberVoiceState: GuildVoiceState @@ -157,12 +153,12 @@ class SkipCommand : AbstractSlashCommand( val musicManager = RobertifyAudioManager[guild] val player = musicManager.player - if (player.playingTrack == null) + if (player?.track == null) return RobertifyEmbedUtils.embedMessage(guild, SkipMessages.NOTHING_TO_SKIP) .build() val neededVotes = getNeededVotes(guild) - val msg = channel.sendEmbed(guild) { + channel.sendEmbed(guild) { embed( SkipMessages.VOTE_SKIP_STARTED_EMBED, Pair("{user}", memberVoiceState.member.asMention), @@ -177,28 +173,28 @@ class SkipCommand : AbstractSlashCommand( danger( id = "voteskip:cancel:${guild.id}" ) - ).await() + ).queue { msg -> + val starter = memberVoiceState.member - val starter = memberVoiceState.member - - LogUtilsKt(guild).sendLog( - LogType.TRACK_VOTE_SKIP, SkipMessages.VOTE_SKIP_STARTED_LOG, - Pair("{user}", starter.asMention) - ) + LogUtilsKt(guild).sendLog( + LogType.TRACK_VOTE_SKIP, SkipMessages.VOTE_SKIP_STARTED_LOG, + Pair("{user}", starter.asMention) + ) - val voteSkipManager = musicManager.voteSkipManager - voteSkipManager.startedBy = starter.idLong - voteSkipManager.voteSkipCount = 1 - voteSkipManager.addVoter(starter.idLong) - voteSkipManager.voteSkipMessage = Pair(channel.idLong, msg.idLong) + val voteSkipManager = musicManager.voteSkipManager + voteSkipManager.startedBy = starter.idLong + voteSkipManager.voteSkipCount = 1 + voteSkipManager.addVoter(starter.idLong) + voteSkipManager.voteSkipMessage = Pair(channel.idLong, msg.idLong) + } return null } - private suspend fun skip(guild: Guild) { + private fun skip(guild: Guild) { val musicManager = RobertifyAudioManager[guild] val audioPlayer = musicManager.player val scheduler = musicManager.scheduler - val playingTrack = audioPlayer.playingTrack + val playingTrack = audioPlayer?.track val queueHandler = scheduler.queueHandler if (playingTrack == null) { @@ -211,46 +207,43 @@ class SkipCommand : AbstractSlashCommand( if (queueHandler.trackRepeating) queueHandler.trackRepeating = false - scheduler.nextTrack(playingTrack, true, audioPlayer.position) + scheduler.nextTrack(playingTrack, true, audioPlayer?.position) clearVoteSkipInfo(guild) } - private suspend fun doVoteSkip(guild: Guild) { + private fun doVoteSkip(guild: Guild) { val voteSkipManager = RobertifyAudioManager[guild].voteSkipManager if (!voteSkipManager.isVoteSkipActive) throw IllegalStateException("Can't do a vote skip when there's none active!") - val msg = guild.getTextChannelById(voteSkipManager.voteSkipMessage!!.first) + guild.getTextChannelById(voteSkipManager.voteSkipMessage!!.first) ?.retrieveMessageById(voteSkipManager.voteSkipMessage!!.second) - ?.await() - - voteSkipManager.voteSkipMessage = null - val track = RobertifyAudioManager[guild] - .player - .playingTrack!! - - runBlocking { - launch { skip(guild) } - } + ?.queue { msg -> + voteSkipManager.voteSkipMessage = null + val track = RobertifyAudioManager[guild] + .player!! + .track!! - msg?.editEmbed { - embed( - SkipMessages.VOTE_SKIPPED, - Pair("{title}", track.title), - Pair("{author}", track.author) - ) - } - ?.setComponents() - ?.queue() + skip(guild) + msg?.editEmbed { + embed( + SkipMessages.VOTE_SKIPPED, + Pair("{title}", track.info.title), + Pair("{author}", track.info.author) + ) + } + ?.setComponents() + ?.queue() - LogUtilsKt(guild).sendLog( - LogType.TRACK_SKIP, SkipMessages.VOTE_SKIPPED_LOG, - Pair("{title}", track.title), - Pair("{author}", track.author) - ) + LogUtilsKt(guild).sendLog( + LogType.TRACK_SKIP, SkipMessages.VOTE_SKIPPED_LOG, + Pair("{title}", track.info.title), + Pair("{author}", track.info.author) + ) + } } - suspend fun clearVoteSkipInfo(guild: Guild) { + fun clearVoteSkipInfo(guild: Guild) { val voteSkipManagerKt = RobertifyAudioManager[guild].voteSkipManager voteSkipManagerKt.clearVoters() voteSkipManagerKt.startedBy = null @@ -259,11 +252,13 @@ class SkipCommand : AbstractSlashCommand( val message = voteSkipManagerKt.voteSkipMessage if (message != null) { - val msg = guild.getTextChannelById(message.first) + guild.getTextChannelById(message.first) ?.retrieveMessageById(message.second) - ?.await() - msg?.editEmbed { embed(SkipMessages.SKIPPED) } - ?.queue { voteSkipManagerKt.voteSkipMessage = null } + ?.queue { msg -> + msg.editEmbed { embed(SkipMessages.SKIPPED) } + .queue { voteSkipManagerKt.voteSkipMessage = null } + } + } } @@ -372,46 +367,47 @@ class SkipCommand : AbstractSlashCommand( ?.retrieveMessageById(message.second) ?.await() val track = RobertifyAudioManager[guild] - .player - .playingTrack!! + .player!! + .track!! voteSkipManager.voteSkipMessage = null clearVoteSkipInfo(guild) msg?.editEmbed { embed( SkipMessages.VOTE_SKIP_CANCELLED, - Pair("{title}", track.title), - Pair("{author}", track.author) + Pair("{title}", track.info.title), + Pair("{author}", track.info.author) ) }?.queue() } } } - private suspend fun updateVoteSkipMessage(guild: Guild) { + private fun updateVoteSkipMessage(guild: Guild) { val voteSkipManager = RobertifyAudioManager[guild].voteSkipManager if (!voteSkipManager.isVoteSkipActive) return val message = voteSkipManager.voteSkipMessage!! - val msg = guild.getTextChannelById(message.first) + guild.getTextChannelById(message.first) ?.retrieveMessageById(message.second) - ?.await() - val neededvotes = getNeededVotes(guild) - msg?.editEmbed { - embed( - SkipMessages.VOTE_SKIP_STARTED_EMBED, - Pair( - "{user}", - GeneralUtils.toMention( - guild, - voteSkipManager.startedBy!!, - GeneralUtils.Mentioner.USER + ?.queue { msg -> + val neededvotes = getNeededVotes(guild) + msg.editEmbed { + embed( + SkipMessages.VOTE_SKIP_STARTED_EMBED, + Pair( + "{user}", + GeneralUtils.toMention( + guild, + voteSkipManager.startedBy!!, + GeneralUtils.Mentioner.USER + ) + ), + Pair("{neededVotes}", neededvotes.toString()) ) - ), - Pair("{neededVotes}", neededvotes.toString()) - ) - }?.queue() + }.queue() + } } override val help: String diff --git a/src/main/kotlin/main/commands/slashcommands/audio/StopCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/StopCommand.kt index c9eb3689..41316cf5 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/StopCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/StopCommand.kt @@ -14,7 +14,6 @@ import main.utils.locale.messages.StopMessages import net.dv8tion.jda.api.entities.Member import net.dv8tion.jda.api.entities.MessageEmbed import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent -import kotlin.time.Duration.Companion.seconds class StopCommand : AbstractSlashCommand( SlashCommand( @@ -39,7 +38,7 @@ class StopCommand : AbstractSlashCommand( val musicManager = RobertifyAudioManager[guild] val player = musicManager.player val scheduler = musicManager.scheduler - val track = player.playingTrack + val track = player?.track return when { !selfVoiceState.inAudioChannel() -> RobertifyEmbedUtils.embedMessage( @@ -66,7 +65,7 @@ class StopCommand : AbstractSlashCommand( else -> { musicManager.clear() player.stopTrack() - logger.debug("Stopped track. Playing track: ${player.playingTrack?.title ?: "none"}") + logger.debug("Stopped track. Playing track: ${player.track?.title ?: "none"}") LogUtilsKt(guild).sendLog( LogType.PLAYER_STOP, diff --git a/src/main/kotlin/main/commands/slashcommands/audio/VolumeCommand.kt b/src/main/kotlin/main/commands/slashcommands/audio/VolumeCommand.kt index c8ea01c2..54c56f91 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/VolumeCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/VolumeCommand.kt @@ -1,6 +1,6 @@ package main.commands.slashcommands.audio -import dev.schlaubi.lavakord.audio.player.applyFilters +import dev.arbjerg.lavalink.protocol.v4.Filters import main.audiohandlers.RobertifyAudioManager import main.commands.slashcommands.SlashCommandManager.getRequiredOption import main.utils.GeneralUtils.isNotNull @@ -44,7 +44,7 @@ class VolumeCommand : AbstractSlashCommand( }.queue() } - private suspend fun handleVolumeChange( + private fun handleVolumeChange( selfVoiceState: GuildVoiceState, memberVoiceState: GuildVoiceState, volume: Int @@ -57,10 +57,8 @@ class VolumeCommand : AbstractSlashCommand( return RobertifyEmbedUtils.embedMessage(guild, VolumeMessages.INVALID_VOLUME) .build() - val player = RobertifyAudioManager[guild].player - player.applyFilters { - this.volume = volume / 100F - } + val player = RobertifyAudioManager[guild].player!! + player.setVolume(volume) RequestChannelConfig(guild).updateMessage() diff --git a/src/main/kotlin/main/commands/slashcommands/audio/filters/EightDFilter.kt b/src/main/kotlin/main/commands/slashcommands/audio/filters/EightDFilter.kt index 80ac2be7..60924a4d 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/filters/EightDFilter.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/filters/EightDFilter.kt @@ -1,7 +1,8 @@ package main.commands.slashcommands.audio.filters -import dev.schlaubi.lavakord.audio.player.rotation +import dev.arbjerg.lavalink.protocol.v4.Rotation import main.commands.slashcommands.audio.filters.internal.handleGenericFilterToggle +import main.utils.GeneralUtils.isNotNull import main.utils.RobertifyEmbedUtils.Companion.replyEmbed import main.utils.component.interactions.slashcommand.AbstractSlashCommand import main.utils.component.interactions.slashcommand.models.SlashCommand @@ -22,18 +23,16 @@ class EightDFilter : AbstractSlashCommand( .queue() } - private suspend fun handle8DToggle(memberVoiceState: GuildVoiceState, selfVoiceState: GuildVoiceState): MessageEmbed = + private fun handle8DToggle(memberVoiceState: GuildVoiceState, selfVoiceState: GuildVoiceState): MessageEmbed = handleGenericFilterToggle( memberVoiceState = memberVoiceState, selfVoiceState = selfVoiceState, filterName = "8D", - filterPredicate = { rotation != null }, + filterPredicate = { rotation.isNotNull() }, filterOn = { - rotation { - rotationHz = 0.05 - } + setRotation(Rotation(0.05)) }, - filterOff = { unsetRotation() } + filterOff = { setRotation(null) } ) override val help: String diff --git a/src/main/kotlin/main/commands/slashcommands/audio/filters/KaraokeFilter.kt b/src/main/kotlin/main/commands/slashcommands/audio/filters/KaraokeFilter.kt index df208f4f..e91918f9 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/filters/KaraokeFilter.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/filters/KaraokeFilter.kt @@ -1,7 +1,8 @@ package main.commands.slashcommands.audio.filters -import dev.schlaubi.lavakord.audio.player.karaoke +import dev.arbjerg.lavalink.protocol.v4.Karaoke import main.commands.slashcommands.audio.filters.internal.handleGenericFilterToggle +import main.utils.GeneralUtils.isNotNull import main.utils.RobertifyEmbedUtils.Companion.replyEmbed import main.utils.component.interactions.slashcommand.AbstractSlashCommand import main.utils.component.interactions.slashcommand.models.SlashCommand @@ -21,9 +22,9 @@ class KaraokeFilter : AbstractSlashCommand( memberVoiceState = event.member!!.voiceState!!, selfVoiceState = event.guild!!.selfMember.voiceState!!, filterName = "Karaoke", - filterPredicate = { karaoke != null }, - filterOn = { karaoke {} }, - filterOff = { unsetKaraoke() } + filterPredicate = { karaoke.isNotNull() }, + filterOn = { setKaraoke(Karaoke()) }, + filterOff = { setKaraoke(null) } ) }.queue() } diff --git a/src/main/kotlin/main/commands/slashcommands/audio/filters/NightcoreFilter.kt b/src/main/kotlin/main/commands/slashcommands/audio/filters/NightcoreFilter.kt index 53e1f191..839e67d2 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/filters/NightcoreFilter.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/filters/NightcoreFilter.kt @@ -1,7 +1,8 @@ package main.commands.slashcommands.audio.filters -import dev.schlaubi.lavakord.audio.player.timescale +import dev.arbjerg.lavalink.protocol.v4.Timescale import main.commands.slashcommands.audio.filters.internal.handleGenericFilterToggle +import main.utils.GeneralUtils.isNotNull import main.utils.RobertifyEmbedUtils.Companion.replyEmbed import main.utils.component.interactions.slashcommand.AbstractSlashCommand import main.utils.component.interactions.slashcommand.models.SlashCommand @@ -20,9 +21,9 @@ class NightcoreFilter : AbstractSlashCommand( handleGenericFilterToggle( event = event, filterName = "Nightcore", - filterPredicate = { timescale != null }, - filterOn = { timescale { pitch = 1.5 } }, - filterOff = { unsetTimescale() } + filterPredicate = { timescale.isNotNull() }, + filterOn = { setTimescale(Timescale(1.5)) }, + filterOff = { setTimescale(null) } ) }.queue() } diff --git a/src/main/kotlin/main/commands/slashcommands/audio/filters/TremoloFilter.kt b/src/main/kotlin/main/commands/slashcommands/audio/filters/TremoloFilter.kt index 95e7d2e7..a4c3a485 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/filters/TremoloFilter.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/filters/TremoloFilter.kt @@ -1,7 +1,8 @@ package main.commands.slashcommands.audio.filters -import dev.schlaubi.lavakord.audio.player.tremolo +import dev.arbjerg.lavalink.protocol.v4.Tremolo import main.commands.slashcommands.audio.filters.internal.handleGenericFilterToggle +import main.utils.GeneralUtils.isNotNull import main.utils.RobertifyEmbedUtils.Companion.replyEmbed import main.utils.component.interactions.slashcommand.AbstractSlashCommand import main.utils.component.interactions.slashcommand.models.SlashCommand @@ -20,9 +21,9 @@ class TremoloFilter : AbstractSlashCommand( handleGenericFilterToggle( event = event, filterName = "Tremolo", - filterPredicate = { tremolo != null }, - filterOn = { tremolo {} }, - filterOff = { unsetTremolo() } + filterPredicate = { tremolo.isNotNull() }, + filterOn = { setTremolo(Tremolo()) }, + filterOff = { setTremolo(null) } ) }.queue() } diff --git a/src/main/kotlin/main/commands/slashcommands/audio/filters/VibratoFilter.kt b/src/main/kotlin/main/commands/slashcommands/audio/filters/VibratoFilter.kt index 66cb5ec3..b89c0fae 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/filters/VibratoFilter.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/filters/VibratoFilter.kt @@ -1,7 +1,8 @@ package main.commands.slashcommands.audio.filters -import dev.schlaubi.lavakord.audio.player.vibrato +import dev.arbjerg.lavalink.protocol.v4.Vibrato import main.commands.slashcommands.audio.filters.internal.handleGenericFilterToggle +import main.utils.GeneralUtils.isNotNull import main.utils.RobertifyEmbedUtils.Companion.replyEmbed import main.utils.component.interactions.slashcommand.AbstractSlashCommand import main.utils.component.interactions.slashcommand.models.SlashCommand @@ -20,9 +21,9 @@ class VibratoFilter : AbstractSlashCommand( handleGenericFilterToggle( event = event, filterName = "Vibrato", - filterPredicate = { vibrato != null }, - filterOn = { vibrato {} }, - filterOff = { unsetVibrato() } + filterPredicate = { vibrato.isNotNull() }, + filterOn = { setVibrato(Vibrato()) }, + filterOff = { setVibrato(null) } ) }.queue() } diff --git a/src/main/kotlin/main/commands/slashcommands/audio/filters/internal/FilterCommandHandlers.kt b/src/main/kotlin/main/commands/slashcommands/audio/filters/internal/FilterCommandHandlers.kt index ac044592..9860750f 100644 --- a/src/main/kotlin/main/commands/slashcommands/audio/filters/internal/FilterCommandHandlers.kt +++ b/src/main/kotlin/main/commands/slashcommands/audio/filters/internal/FilterCommandHandlers.kt @@ -1,7 +1,7 @@ package main.commands.slashcommands.audio.filters.internal -import dev.schlaubi.lavakord.audio.player.Filters -import dev.schlaubi.lavakord.audio.player.applyFilters +import dev.arbjerg.lavalink.client.protocol.FilterBuilder +import dev.arbjerg.lavalink.protocol.v4.Filters import main.audiohandlers.RobertifyAudioManager import main.utils.GeneralUtils import main.utils.GeneralUtils.isNotNull @@ -16,12 +16,12 @@ import net.dv8tion.jda.api.entities.GuildVoiceState import net.dv8tion.jda.api.entities.MessageEmbed import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent -internal suspend inline fun handleGenericFilterToggle( +internal inline fun handleGenericFilterToggle( event: SlashCommandInteractionEvent, filterName: String, filterPredicate: Filters.() -> Boolean, - noinline filterOn: Filters.() -> Unit, - noinline filterOff: Filters.() -> Unit + noinline filterOn: FilterBuilder.() -> FilterBuilder, + noinline filterOff: FilterBuilder.() -> FilterBuilder ): MessageEmbed = handleGenericFilterToggle( memberVoiceState = event.member!!.voiceState!!, @@ -32,25 +32,25 @@ internal suspend inline fun handleGenericFilterToggle( filterOff ) -internal suspend inline fun handleGenericFilterToggle( +internal inline fun handleGenericFilterToggle( memberVoiceState: GuildVoiceState, selfVoiceState: GuildVoiceState, filterName: String, filterPredicate: Filters.() -> Boolean, - noinline filterOn: Filters.() -> Unit, - noinline filterOff: Filters.() -> Unit + noinline filterOn: FilterBuilder.() -> FilterBuilder, + noinline filterOff: FilterBuilder.() -> FilterBuilder ): MessageEmbed { val acChecks = audioChannelChecks(memberVoiceState, selfVoiceState, songMustBePlaying = true) if (acChecks.isNotNull()) return acChecks!! val guild = selfVoiceState.guild - val player = RobertifyAudioManager[guild].player + val player = RobertifyAudioManager[guild].player!! val filters = player.filters val logUtils = LogUtilsKt(guild) val localeManager = LocaleManager[guild] return if (filterPredicate(filters)) { - player.applyFilters(filterOff) + player.setFilters(filterOff(FilterBuilder()).build()) logUtils.sendLog( LogType.FILTER_TOGGLE, "${memberVoiceState.member.asMention} ${ @@ -69,7 +69,7 @@ internal suspend inline fun handleGenericFilterToggle( GeneralUtils.Pair("{status}", GeneralMessages.OFF_STATUS, localeManager) ).build() } else { - player.applyFilters(filterOn) + player.setFilters(filterOn(FilterBuilder()).build()) logUtils.sendLog( LogType.FILTER_TOGGLE, "${memberVoiceState.member.asMention} ${ diff --git a/src/main/kotlin/main/commands/slashcommands/dev/EvalCommand.kt b/src/main/kotlin/main/commands/slashcommands/dev/EvalCommand.kt index bf6018e3..f185b61b 100644 --- a/src/main/kotlin/main/commands/slashcommands/dev/EvalCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/dev/EvalCommand.kt @@ -70,7 +70,7 @@ class EvalCommand : AbstractSlashCommand( engine.put("shards", event.jda.shardManager!!) engine.put("guild", event.guild!!) engine.put("member", event.member!!) - engine.put("link", Robertify.lavaKord) + engine.put("link", Robertify.lavalink) engine.put("requester", HttpClient(CIO)) engine.put("http", OkHttpClient()) // TODO: Add RobertifyAPI diff --git a/src/main/kotlin/main/commands/slashcommands/dev/NodeInfoCommand.kt b/src/main/kotlin/main/commands/slashcommands/dev/NodeInfoCommand.kt index ab34df58..87216014 100644 --- a/src/main/kotlin/main/commands/slashcommands/dev/NodeInfoCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/dev/NodeInfoCommand.kt @@ -17,10 +17,10 @@ class NodeInfoCommand : AbstractSlashCommand( ) { override suspend fun handle(event: SlashCommandInteractionEvent) { - val lavalink = Robertify.lavaKord + val lavalink = Robertify.lavalink val desc = "```txt\n${ lavalink.nodes.joinToString("\n") { node -> - val stats = node.lastStatsEvent + val stats = node.stats if (stats == null) """ diff --git a/src/main/kotlin/main/commands/slashcommands/dev/SendAlertCommand.kt b/src/main/kotlin/main/commands/slashcommands/dev/SendAlertCommand.kt index 95aebd56..ec2d19d0 100644 --- a/src/main/kotlin/main/commands/slashcommands/dev/SendAlertCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/dev/SendAlertCommand.kt @@ -1,7 +1,7 @@ package main.commands.slashcommands.dev import dev.minn.jda.ktx.interactions.components.* -import main.audiohandlers.loaders.MainAudioLoader.Companion.queueThenDelete +import main.audiohandlers.loaders.MainAudioLoader.Companion.queueThenDeleteCoroutine import main.commands.slashcommands.SlashCommandManager.getRequiredValue import main.utils.RobertifyEmbedUtils.Companion.replyEmbed import main.utils.component.interactions.slashcommand.AbstractSlashCommand @@ -111,7 +111,7 @@ class SendAlertCommand : AbstractSlashCommand( .map { it.asDisabled() } ) ) - .queueThenDelete(time = 1) + .queueThenDeleteCoroutine(time = 1) } } \ No newline at end of file diff --git a/src/main/kotlin/main/commands/slashcommands/dev/UpdateCommand.kt b/src/main/kotlin/main/commands/slashcommands/dev/UpdateCommand.kt index 33185d31..a8c7702b 100644 --- a/src/main/kotlin/main/commands/slashcommands/dev/UpdateCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/dev/UpdateCommand.kt @@ -99,7 +99,7 @@ class UpdateCommand : AbstractSlashCommand( successMsg = "Successfully updated all request channel buttons!", errorMsg = "Could not update all request channel buttons!" ) { - it.updateButtons()?.await() + it.updateButtons() } } @@ -119,7 +119,7 @@ class UpdateCommand : AbstractSlashCommand( successMsg = "Successfully updated all request channel topics!", errorMsg = "Could not update all request channel topics!" ) { - it.updateTopic()?.await() + it.updateTopic() } } diff --git a/src/main/kotlin/main/commands/slashcommands/management/requestchannel/RequestChannelEditCommand.kt b/src/main/kotlin/main/commands/slashcommands/management/requestchannel/RequestChannelEditCommand.kt index 6f2d4b33..57a89994 100644 --- a/src/main/kotlin/main/commands/slashcommands/management/requestchannel/RequestChannelEditCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/management/requestchannel/RequestChannelEditCommand.kt @@ -7,7 +7,7 @@ import dev.minn.jda.ktx.messages.send import dev.minn.jda.ktx.util.SLF4J import kotlinx.coroutines.* import main.audiohandlers.RobertifyAudioManager -import main.audiohandlers.loaders.MainAudioLoader.Companion.queueThenDelete +import main.audiohandlers.loaders.MainAudioLoader.Companion.queueThenDeleteCoroutine import main.constants.RobertifyEmoji import main.constants.Toggle import main.main.Robertify @@ -131,7 +131,7 @@ class RequestChannelEditCommand : AbstractSlashCommand( config.setOriginalAnnouncementToggle(TogglesConfig(guild).getToggle(Toggle.ANNOUNCE_MESSAGES)) try { - if (RobertifyAudioManager[guild].player.playingTrack != null) + if (RobertifyAudioManager[guild].player?.track!= null) config.updateMessage() } catch (_: UninitializedPropertyAccessException) { } @@ -255,7 +255,7 @@ class RequestChannelEditCommand : AbstractSlashCommand( buttonNames: List, event: ButtonInteractionEvent? = null, shardManager: ShardManager = Robertify.shardManager - ): Deferred? { + ): CompletableFuture? { val localeManager = LocaleManager[guild] val config = RequestChannelConfig(guild, shardManager) val subConfig = config.config @@ -330,7 +330,7 @@ class RequestChannelEditCommand : AbstractSlashCommand( Pair("{button}", buttons[i]), Pair("{status}", localeManager.getMessage(GeneralMessages.ON_STATUS)) ) - }.queueThenDelete(time = 15, unit = TimeUnit.SECONDS) + }.queueThenDeleteCoroutine(time = 15, unit = TimeUnit.SECONDS) } else { event.hook.sendEmbed(guild) { embed( @@ -338,7 +338,7 @@ class RequestChannelEditCommand : AbstractSlashCommand( Pair("{button}", buttons[i]), Pair("{status}", localeManager.getMessage(GeneralMessages.OFF_STATUS)) ) - }.queueThenDelete(time = 15, unit = TimeUnit.SECONDS) + }.queueThenDeleteCoroutine(time = 15, unit = TimeUnit.SECONDS) } } diff --git a/src/main/kotlin/main/commands/slashcommands/management/requestchannel/RequestChannelEvents.kt b/src/main/kotlin/main/commands/slashcommands/management/requestchannel/RequestChannelEvents.kt index f9ad3c0e..a2764a33 100644 --- a/src/main/kotlin/main/commands/slashcommands/management/requestchannel/RequestChannelEvents.kt +++ b/src/main/kotlin/main/commands/slashcommands/management/requestchannel/RequestChannelEvents.kt @@ -223,7 +223,7 @@ class RequestChannelEvents : AbstractEventController() { val musicManager = RobertifyAudioManager[guild] val scheduler = musicManager.scheduler val queueHandler = scheduler.queueHandler - val playingTrack = musicManager.player.playingTrack + val playingTrack = musicManager.player?.track val logUtils = LogUtilsKt(guild) val member = memberVoiceState.member diff --git a/src/main/kotlin/main/commands/slashcommands/misc/PlaytimeCommand.kt b/src/main/kotlin/main/commands/slashcommands/misc/PlaytimeCommand.kt index 500591ab..43d68bd8 100644 --- a/src/main/kotlin/main/commands/slashcommands/misc/PlaytimeCommand.kt +++ b/src/main/kotlin/main/commands/slashcommands/misc/PlaytimeCommand.kt @@ -38,8 +38,8 @@ class PlaytimeCommand : AbstractSlashCommand( if (playtime[guild.idLong] == null) 0 else playtime[guild.idLong]!! ) + ( - if (player.playingTrack == null) 0 - else player.playingTrack?.length ?: 0 + if (player?.track== null) 0 + else player.track?.length ?: 0 ) return RobertifyEmbedUtils.embedMessage( diff --git a/src/main/kotlin/main/constants/BotConstants.kt b/src/main/kotlin/main/constants/BotConstants.kt index 2e11ad35..88bcdf14 100644 --- a/src/main/kotlin/main/constants/BotConstants.kt +++ b/src/main/kotlin/main/constants/BotConstants.kt @@ -16,14 +16,14 @@ object BotConstants { const val DEFAULT_IMAGE = "https://i.imgur.com/VNQvjve.png" const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" - suspend fun getInsufficientPermsMessage(guild: Guild?, vararg permsNeeded: RobertifyPermission?): String { + fun getInsufficientPermsMessage(guild: Guild?, vararg permsNeeded: RobertifyPermission?): String { return LocaleManager[guild].getMessage( GeneralMessages.INSUFFICIENT_PERMS, Pair("{permissions}", permsNeeded.mapNotNull { it?.name }.joinToString(", ")) ) } - suspend fun getUnexpectedErrorEmbed(guild: Guild?): MessageEmbed { + fun getUnexpectedErrorEmbed(guild: Guild?): MessageEmbed { return RobertifyEmbedUtils.embedMessage(guild, GeneralMessages.UNEXPECTED_ERROR) .build() } diff --git a/src/main/kotlin/main/events/VoiceChannelEvents.kt b/src/main/kotlin/main/events/VoiceChannelEvents.kt index 8ce432cd..ac90edb6 100644 --- a/src/main/kotlin/main/events/VoiceChannelEvents.kt +++ b/src/main/kotlin/main/events/VoiceChannelEvents.kt @@ -42,7 +42,7 @@ class VoiceChannelEvents : AbstractEventController() { ) { if (guildConfig.getTwentyFourSevenMode() || guildDisconnector.disconnectScheduled() || channelLeft.members.size > 1) return@onEvent - guildMusicManager.player.pause(true) + guildMusicManager.player?.setPaused(true) guildDisconnector.scheduleDisconnect() } @@ -54,7 +54,7 @@ class VoiceChannelEvents : AbstractEventController() { */ else if (channelJoined != null && channelJoined.id == selfVoiceState.channel!!.id && guildDisconnector.disconnectScheduled()) { guildDisconnector.cancelDisconnect() - guildMusicManager.player.pause(false) + guildMusicManager.player?.setPaused(false) } } catch (e: UninitializedPropertyAccessException) { diff --git a/src/main/kotlin/main/main/Robertify.kt b/src/main/kotlin/main/main/Robertify.kt index dacc6fda..1e11f26b 100644 --- a/src/main/kotlin/main/main/Robertify.kt +++ b/src/main/kotlin/main/main/Robertify.kt @@ -5,17 +5,15 @@ import api.RobertifyKtorApi import com.adamratzman.spotify.SpotifyAppApi import com.adamratzman.spotify.spotifyAppApi import com.google.common.util.concurrent.ThreadFactoryBuilder +import dev.arbjerg.lavalink.client.LavalinkClient +import dev.arbjerg.lavalink.client.TrackStartEvent +import dev.arbjerg.lavalink.client.loadbalancing.RegionGroup +import dev.arbjerg.lavalink.libraries.jda.JDAVoiceUpdateListener import dev.minn.jda.ktx.events.CoroutineEventManager import dev.minn.jda.ktx.events.getDefaultScope import dev.minn.jda.ktx.events.listener import dev.minn.jda.ktx.jdabuilder.injectKTX import dev.minn.jda.ktx.util.SLF4J -import dev.schlaubi.lavakord.LavaKord -import dev.schlaubi.lavakord.MutableLavaKordOptions -import dev.schlaubi.lavakord.jda.LavaKordShardManager -import dev.schlaubi.lavakord.jda.applyLavakord -import dev.schlaubi.lavakord.jda.lavakord -import dev.schlaubi.lavakord.plugins.lavasrc.LavaSrc import io.sentry.Sentry import kotlinx.coroutines.* import main.audiohandlers.RobertifyAudioManager @@ -38,6 +36,7 @@ import main.utils.json.requestchannel.RequestChannelConfig import main.utils.locale.LocaleManager import net.dv8tion.jda.api.OnlineStatus import net.dv8tion.jda.api.entities.Activity +import net.dv8tion.jda.api.entities.GuildVoiceState import net.dv8tion.jda.api.events.guild.GuildReadyEvent import net.dv8tion.jda.api.events.session.ReadyEvent import net.dv8tion.jda.api.events.session.ShutdownEvent @@ -59,7 +58,7 @@ object Robertify { private val logger by SLF4J val cronScheduler = StdSchedulerFactory.getDefaultScheduler() var topGGAPI: DiscordBotListAPI? = null - lateinit var lavaKord: LavaKord + lateinit var lavalink: LavalinkClient private set lateinit var shardManager: ShardManager private set @@ -68,8 +67,6 @@ object Robertify { lateinit var externalApi: RobertifyApi private set - private val lavakordShardManager = LavaKordShardManager() - fun main() = runBlocking { if (Config.hasValue(ENV.SENTRY_DSN)) @@ -85,13 +82,9 @@ object Robertify { Runtime.getRuntime().addShutdownHook(mainShutdownHook.newThread { logger.info("Destroying all players (If any left)") runBlocking { - RobertifyAudioManager.musicManagers - .values - .forEach { musicManager -> -// if (musicManager.player.playingTrack != null) -// GuildResumeManager(musicManager.guild).saveTracks() - musicManager.destroy() - } + shardManager.guilds + .filter { guild -> guild.selfMember.voiceState != null } + .forEach { guild -> guild.jda.directAudioController.disconnect(guild) } } }) @@ -111,9 +104,27 @@ object Robertify { AbstractMongoDatabase.initAllCaches() logger.info("Initialized all caches.") + + // Setup LavaLink + logger.info("Setting up LavaLink...") + lavalink = LavalinkClient(getIdFromToken(Config.BOT_TOKEN).toLong()) + lavalink.on() + .subscribe { event -> + logger.info("LavaLink ready on node ${event.node.name}. Session ID is ${event.sessionId}") + } + + Config.LAVA_NODES.forEach { node -> + lavalink.addNode( + address = node.uri, + password = node.password, + name = node.name, + regionFilter = RegionGroup.US + ) + logger.info("Registered lava node with address: ${node.uri}") + } + // Build bot connection logger.info("Building shard manager...") - val shardManagerBuilder = DefaultShardManagerBuilder.createLight( Config.BOT_TOKEN, listOf(GatewayIntent.GUILD_VOICE_STATES, GatewayIntent.GUILD_MESSAGE_REACTIONS), @@ -124,6 +135,7 @@ object Robertify { setMemberCachePolicy(MemberCachePolicy.DEFAULT) setBulkDeleteSplittingEnabled(false) enableCache(CacheFlag.VOICE_STATE) + setVoiceDispatchInterceptor(JDAVoiceUpdateListener(lavalink)) setActivity(Activity.listening("Starting up...")) val disabledIntents = mutableListOf( @@ -147,33 +159,9 @@ object Robertify { disableIntents(disabledIntents) } - shardManagerBuilder.applyLavakord(lavakordShardManager) shardManager = shardManagerBuilder.build() logger.info("Successfully built shard manager") - logger.info("Setting up LavaKord...") - lavaKord = shardManager.lavakord( - lavakordShardManager, getDefaultScope().coroutineContext, options = MutableLavaKordOptions( - link = MutableLavaKordOptions.LinkConfig( - showTrace = true - ) - ) - ) { - plugins { - install(LavaSrc) - } - } - - Config.LAVA_NODES.forEach { node -> - lavaKord.addNode( - serverUri = node.uri.toString(), - password = node.password, - name = node.name - ) - logger.info("Registered lava node with address: ${node.uri}") - } - logger.info("LavaKord ready") - shardManager.handleShardReady() shardManager.handleGuildReady() diff --git a/src/main/kotlin/main/utils/GeneralUtils.kt b/src/main/kotlin/main/utils/GeneralUtils.kt index f70efd45..31b7b0b7 100644 --- a/src/main/kotlin/main/utils/GeneralUtils.kt +++ b/src/main/kotlin/main/utils/GeneralUtils.kt @@ -119,7 +119,7 @@ object GeneralUtils { fun String.stripDigits(): String = this.replace("\\d".toRegex(), "") - suspend fun Member?.hasPermissions(vararg perms: RobertifyPermission): Boolean { + fun Member?.hasPermissions(vararg perms: RobertifyPermission): Boolean { if (this == null) return false if (hasPermission(Permission.ADMINISTRATOR) || isOwner) @@ -143,7 +143,7 @@ object GeneralUtils { return pass >= perms.size } - suspend fun hasPerms(guild: Guild, sender: Member?, vararg perms: RobertifyPermission): Boolean { + fun hasPerms(guild: Guild, sender: Member?, vararg perms: RobertifyPermission): Boolean { if (sender == null) return false @@ -460,14 +460,14 @@ object GeneralUtils { } } - suspend fun setDefaultEmbed(guild: Guild) { + fun setDefaultEmbed(guild: Guild) { val theme = ThemesConfig(guild).getTheme() RobertifyEmbedUtils.setEmbedBuilder(guild) { EmbedBuilder().setColor(theme.color) } } - suspend fun setCustomEmbed(guild: Guild, author: String? = null, footer: String? = null) { + fun setCustomEmbed(guild: Guild, author: String? = null, footer: String? = null) { val theme = ThemesConfig(guild).getTheme() RobertifyEmbedUtils.setEmbedBuilder(guild) { EmbedBuilder() @@ -521,7 +521,7 @@ object GeneralUtils { CHANNEL } - suspend fun listOfIDsToMentions(guild: Guild?, mentions: List, mentioner: Mentioner): String { + fun listOfIDsToMentions(guild: Guild?, mentions: List, mentioner: Mentioner): String { val mentionTag: String = when (mentioner) { Mentioner.USER -> "@" Mentioner.ROLE -> "@&" @@ -537,16 +537,16 @@ object GeneralUtils { } } - suspend fun toMention(guild: Guild? = null, id: Long, mentioner: Mentioner): String = + fun toMention(guild: Guild? = null, id: Long, mentioner: Mentioner): String = listOfIDsToMentions(guild, listOf(id), mentioner) - suspend fun toMention(guild: Guild? = null, id: String, mentioner: Mentioner): String = + fun toMention(guild: Guild? = null, id: String, mentioner: Mentioner): String = listOfIDsToMentions(guild, listOf(id.toLong()), mentioner) - suspend fun Long.toMention(mentioner: Mentioner, guild: Guild? = null): String = + fun Long.toMention(mentioner: Mentioner, guild: Guild? = null): String = listOfIDsToMentions(guild, listOf(this), mentioner) - suspend fun String.toMention(mentioner: Mentioner, guild: Guild? = null): String = + fun String.toMention(mentioner: Mentioner, guild: Guild? = null): String = listOfIDsToMentions(guild, listOf(this.toLong()), mentioner) fun getID(obj: JSONObject, field: String): Long = try { @@ -557,7 +557,7 @@ object GeneralUtils { fun getID(obj: JSONObject, field: GenericJSONField): Long = getID(obj, field.toString()) - suspend fun checkPremium(guild: Guild, event: GenericComponentInteractionCreateEvent): Boolean { + fun checkPremium(guild: Guild, event: GenericComponentInteractionCreateEvent): Boolean { // TODO: Guild config premium check event.replyEmbeds( @@ -572,7 +572,7 @@ object GeneralUtils { return false } - suspend fun checkPremium(guild: Guild, event: GenericCommandInteractionEvent): Boolean { + fun checkPremium(guild: Guild, event: GenericCommandInteractionEvent): Boolean { // TODO: Guild config premium check event.replyEmbeds( @@ -587,7 +587,7 @@ object GeneralUtils { return false } - suspend fun checkPremium(guild: Guild, user: User, msg: Message): Boolean { + fun checkPremium(guild: Guild, user: User, msg: Message): Boolean { // TODO: Guild config premium check msg.reply(user.asMention) @@ -610,13 +610,14 @@ object GeneralUtils { return false } - suspend fun dmUser(user: User, message: LocaleMessage) { - val channel = user.openPrivateChannel().await() - channel.sendMessageEmbeds(RobertifyEmbedUtils.embedMessage(message).build()) - .queue(null) { - ErrorHandler() - .ignore(ErrorResponse.CANNOT_SEND_TO_USER) - } + fun dmUser(user: User, message: LocaleMessage) { + user.openPrivateChannel().queue { channel -> + channel.sendMessageEmbeds(RobertifyEmbedUtils.embedMessage(message).build()) + .queue(null) { + ErrorHandler() + .ignore(ErrorResponse.CANNOT_SEND_TO_USER) + } + } } fun dmUser(user: User, message: MessageEmbed) { @@ -639,13 +640,14 @@ object GeneralUtils { } } - suspend fun User.dmEmbed(message: LocaleMessage, vararg placeholders: Pair) { - val channel = openPrivateChannel().await() - channel.sendEmbed { - embed(message, *placeholders) - }.queue(null) { - ErrorHandler() - .ignore(ErrorResponse.CANNOT_SEND_TO_USER) + fun User.dmEmbed(message: LocaleMessage, vararg placeholders: Pair) { + openPrivateChannel().queue { channel -> + channel.sendEmbed { + embed(message, *placeholders) + }.queue(null) { + ErrorHandler() + .ignore(ErrorResponse.CANNOT_SEND_TO_USER) + } } } @@ -672,7 +674,7 @@ object GeneralUtils { fun Any?.isNotNull(): Boolean = this != null - suspend fun Pair(first: A, second: B, localeManager: LocaleManager): Pair = + fun Pair(first: A, second: B, localeManager: LocaleManager): Pair = Pair(first, localeManager.getMessage(second)) fun RestAction.queueAfter(duration: kotlin.time.Duration) = @@ -691,7 +693,7 @@ object GeneralUtils { suspend fun RestAction.queueCoroutine( context: CoroutineContext = getDefaultScope().coroutineContext, duration: kotlin.time.Duration = kotlin.time.Duration.ZERO, - onSuccess: (suspend (item: T) -> Unit)? = null + onSuccess: ((item: T) -> Unit)? = null ) { withContext(context) { delay(duration) diff --git a/src/main/kotlin/main/utils/RobertifyEmbedUtils.kt b/src/main/kotlin/main/utils/RobertifyEmbedUtils.kt index ec1987a5..1aa80b5b 100644 --- a/src/main/kotlin/main/utils/RobertifyEmbedUtils.kt +++ b/src/main/kotlin/main/utils/RobertifyEmbedUtils.kt @@ -1,5 +1,6 @@ package main.utils +import kotlinx.coroutines.runBlocking import main.utils.json.requestchannel.RequestChannelConfig import main.utils.locale.LocaleManager import main.utils.locale.LocaleMessage @@ -40,7 +41,7 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) } } - suspend fun getDefaultEmbed(guild: Guild?): EmbedBuilder { + fun getDefaultEmbed(guild: Guild?): EmbedBuilder { if (guild == null) return getDefaultEmbed() @@ -62,7 +63,7 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) guildEmbedSuppliers[0L] = supplier } - suspend fun getEmbedBuilder(guild: Guild?): EmbedBuilder { + fun getEmbedBuilder(guild: Guild?): EmbedBuilder { if (guild == null) return getDefaultEmbed() @@ -76,18 +77,18 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) } } - suspend fun embedMessage(guild: Guild?, message: String): EmbedBuilder { + fun embedMessage(guild: Guild?, message: String): EmbedBuilder { val builder = if (guild == null) getDefaultEmbed() else getDefaultEmbed(guild) return builder.setDescription(message) } - suspend fun embedMessage(guild: Guild?, message: LocaleMessage): EmbedBuilder { + fun embedMessage(guild: Guild?, message: LocaleMessage): EmbedBuilder { if (guild == null) return embedMessage(message) val localeManager = LocaleManager[guild] return getDefaultEmbed(guild).setDescription(localeManager.getMessage(message)) } - suspend fun embedMessage(message: LocaleMessage): EmbedBuilder { + fun embedMessage(message: LocaleMessage): EmbedBuilder { val localeManager = LocaleManager.globalManager() return getDefaultEmbed().setDescription(localeManager.getMessage(message)) } @@ -96,7 +97,7 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) return getDefaultEmbed().setDescription(message) } - suspend fun embedMessage( + fun embedMessage( guild: Guild?, message: LocaleMessage, vararg placeholders: Pair @@ -106,30 +107,30 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) .setDescription(localeManager.getMessage(message, *placeholders)) } - suspend fun embedMessageWithTitle(guild: Guild?, title: String, message: String): EmbedBuilder { + fun embedMessageWithTitle(guild: Guild?, title: String, message: String): EmbedBuilder { return getDefaultEmbed(guild).setTitle(title).setDescription(message) } - suspend fun embedMessageWithTitle(guild: Guild?, title: LocaleMessage, message: LocaleMessage): EmbedBuilder { + fun embedMessageWithTitle(guild: Guild?, title: LocaleMessage, message: LocaleMessage): EmbedBuilder { val localeManager = LocaleManager[guild] return getDefaultEmbed(guild).setTitle(localeManager.getMessage(title)) .setDescription(localeManager.getMessage(message)) } - suspend fun embedMessageWithTitle(guild: Guild?, title: String, message: LocaleMessage): EmbedBuilder { + fun embedMessageWithTitle(guild: Guild?, title: String, message: LocaleMessage): EmbedBuilder { val localeManager = LocaleManager[guild] return getDefaultEmbed(guild).setTitle(title) .setDescription(localeManager.getMessage(message)) } - suspend fun embedMessageWithTitle(guild: Guild?, title: LocaleMessage, message: String): EmbedBuilder { + fun embedMessageWithTitle(guild: Guild?, title: LocaleMessage, message: String): EmbedBuilder { val localeManager = LocaleManager[guild] return getDefaultEmbed(guild).setTitle(localeManager.getMessage(title)) .setDescription(message) } @SafeVarargs - suspend fun embedMessageWithTitle( + fun embedMessageWithTitle( guild: Guild?, title: LocaleMessage, message: LocaleMessage, @@ -141,7 +142,7 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) } @SafeVarargs - suspend fun embedMessageWithTitle( + fun embedMessageWithTitle( guild: Guild?, title: String, message: LocaleMessage, @@ -153,7 +154,7 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) } @SafeVarargs - suspend fun embedMessageWithTitle( + fun embedMessageWithTitle( guild: Guild?, title: LocaleMessage, message: String, @@ -164,7 +165,7 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) .setDescription(message) } - suspend fun getEphemeralState(channel: GuildMessageChannel, default: Boolean = false): Boolean { + fun getEphemeralState(channel: GuildMessageChannel, default: Boolean = false): Boolean { val dedicatedChannelConfig = RequestChannelConfig(channel.guild) return if (!dedicatedChannelConfig.isChannelSet()) default else dedicatedChannelConfig.getChannelId() == channel.idLong } @@ -174,12 +175,12 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) return sendMessageEmbeds(supplier(embedUtils)) } - suspend fun InteractionHook.sendEmbed(guild: Guild? = null, message: LocaleMessage, vararg placeholders: Pair): WebhookMessageCreateAction { + fun InteractionHook.sendEmbed(guild: Guild? = null, message: LocaleMessage, vararg placeholders: Pair): WebhookMessageCreateAction { val embedUtils = getGuildUtils(guild) return sendMessageEmbeds(embedUtils.embed(message, *placeholders)) } - suspend fun InteractionHook.sendEmbed(guild: Guild? = null, message: String): WebhookMessageCreateAction { + fun InteractionHook.sendEmbed(guild: Guild? = null, message: String): WebhookMessageCreateAction { val embedUtils = getGuildUtils(guild) return sendMessageEmbeds(embedUtils.embed(message)) } @@ -189,7 +190,7 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) return editOriginalEmbeds(supplier(embedUtils)) } - suspend fun InteractionHook.editEmbed(guild: Guild? = null, message: LocaleMessage, vararg placeholders: Pair): WebhookMessageEditAction { + fun InteractionHook.editEmbed(guild: Guild? = null, message: LocaleMessage, vararg placeholders: Pair): WebhookMessageEditAction { val embedUtils = getGuildUtils(guild) return editOriginalEmbeds(embedUtils.embed(message, *placeholders)) } @@ -199,7 +200,7 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) return sendMessageEmbeds(supplier(embedUtils)) } - suspend fun MessageChannel.sendEmbed(guild: Guild? = null, message: LocaleMessage, vararg placeholders: Pair): MessageCreateAction { + fun MessageChannel.sendEmbed(guild: Guild? = null, message: LocaleMessage, vararg placeholders: Pair): MessageCreateAction { val embedUtils = getGuildUtils(guild) return sendMessageEmbeds(embedUtils.embed(message, *placeholders)) } @@ -208,7 +209,7 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) return this.sendEmbed(guild, supplier) } - suspend fun GuildMessageChannel.sendEmbed(message: LocaleMessage, vararg placeholders: Pair): MessageCreateAction { + fun GuildMessageChannel.sendEmbed(message: LocaleMessage, vararg placeholders: Pair): MessageCreateAction { return this.sendEmbed(guild, message, *placeholders) } @@ -222,12 +223,12 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) return replyEmbeds(supplier(embedUtils)) } - suspend fun IReplyCallback.replyEmbed(message: LocaleMessage, vararg placeholders: Pair): ReplyCallbackAction { + fun IReplyCallback.replyEmbed(message: LocaleMessage, vararg placeholders: Pair): ReplyCallbackAction { val embedUtils = getGuildUtils(guild) return replyEmbeds(embedUtils.embed(message, *placeholders)) } - suspend fun IReplyCallback.replyEmbed(message: String): ReplyCallbackAction { + fun IReplyCallback.replyEmbed(message: String): ReplyCallbackAction { val embedUtils = getGuildUtils(guild) return replyEmbeds(embedUtils.embed(message)) } @@ -237,29 +238,29 @@ class RobertifyEmbedUtils private constructor(private val guild: Guild? = null) return editMessageEmbeds(supplier(embedUtils)) } - suspend fun EmbedBuilder.addField(guild: Guild? = null, name: LocaleMessage, value: LocaleMessage, inline: Boolean = false): EmbedBuilder { + fun EmbedBuilder.addField(guild: Guild? = null, name: LocaleMessage, value: LocaleMessage, inline: Boolean = false): EmbedBuilder { val localeManager = LocaleManager[guild] return addField(localeManager.getMessage(name), localeManager.getMessage(value), inline) } - suspend fun EmbedBuilder.addField(guild: Guild? = null, name: LocaleMessage, value: String, inline: Boolean = false): EmbedBuilder { + fun EmbedBuilder.addField(guild: Guild? = null, name: LocaleMessage, value: String, inline: Boolean = false): EmbedBuilder { val localeManager = LocaleManager[guild] return addField(localeManager.getMessage(name), value, inline) } } - suspend fun embed(description: LocaleMessage, title: LocaleMessage, vararg placeholders: Pair): MessageEmbed = + fun embed(description: LocaleMessage, title: LocaleMessage, vararg placeholders: Pair): MessageEmbed = embedMessageWithTitle(guild, title, description, *placeholders).build() - suspend fun embed(title: LocaleMessage, description: String, vararg placeholders: Pair): MessageEmbed = + fun embed(title: LocaleMessage, description: String, vararg placeholders: Pair): MessageEmbed = embedMessageWithTitle(guild, title, description, *placeholders).build() - suspend fun embed(description: LocaleMessage, vararg placeholders: Pair): MessageEmbed = + fun embed(description: LocaleMessage, vararg placeholders: Pair): MessageEmbed = embedMessage(guild, description, *placeholders).build() - suspend fun embedBuilder(description: LocaleMessage, vararg placeholders: Pair): EmbedBuilder = + fun embedBuilder(description: LocaleMessage, vararg placeholders: Pair): EmbedBuilder = embedMessage(guild, description, *placeholders) - suspend fun embed(description: String): MessageEmbed = + fun embed(description: String): MessageEmbed = embedMessage(guild, description).build() } \ No newline at end of file diff --git a/src/main/kotlin/main/utils/api/robertify/imagebuilders/builders/QueueImageBuilder.kt b/src/main/kotlin/main/utils/api/robertify/imagebuilders/builders/QueueImageBuilder.kt index 8f8c7a3b..0521bec8 100644 --- a/src/main/kotlin/main/utils/api/robertify/imagebuilders/builders/QueueImageBuilder.kt +++ b/src/main/kotlin/main/utils/api/robertify/imagebuilders/builders/QueueImageBuilder.kt @@ -37,7 +37,7 @@ data class QueueImageBuilder( } fun addTrack(index: Int, track: Track): QueueImageBuilder = - addTrack(index, track.title, track.author, track.length) + addTrack(index, track.info.title, track.info.author, track.info.length) override suspend fun build(): InputStream? { require(obj.has(QueryFields.TRACKS.toString())) { "The track list must be provided before building the queue image!" } diff --git a/src/main/kotlin/main/utils/component/interactions/slashcommand/AbstractSlashCommand.kt b/src/main/kotlin/main/utils/component/interactions/slashcommand/AbstractSlashCommand.kt index cdb1ce8f..0f48cd25 100644 --- a/src/main/kotlin/main/utils/component/interactions/slashcommand/AbstractSlashCommand.kt +++ b/src/main/kotlin/main/utils/component/interactions/slashcommand/AbstractSlashCommand.kt @@ -147,7 +147,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand * @param songMustBePlaying If the bot needs to be playing a song for the command to be executed. * @return An embed of the error message, null if all the checks passed. */ - suspend fun audioChannelChecks( + fun audioChannelChecks( memberVoiceState: GuildVoiceState, selfVoiceState: GuildVoiceState, selfChannelNeeded: Boolean = true, @@ -179,9 +179,8 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand GeneralMessages.SAME_VOICE_CHANNEL ).build() - val playingTrack = RobertifyAudioManager[guild] - .player - .playingTrack + val player = RobertifyAudioManager[guild].player + val playingTrack = player?.track if (songMustBePlaying && playingTrack == null) return RobertifyEmbedUtils.embedMessage( guild, @@ -192,7 +191,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand } } - fun register(shardManager: ShardManager) { + suspend fun register(shardManager: ShardManager) { shardManager.onCommand(this.info.name) { event -> if (event !is SlashCommandInteractionEvent) return@onCommand @@ -203,19 +202,15 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand handle(event) - coroutineScope { - launch { - if (!SlashCommandManager.isDevCommand(this@AbstractSlashCommand)) { - try { - CommandInfluxDatabase.recordCommand( - guild = event.guild, - command = this@AbstractSlashCommand, - executor = event.user - ) - } catch (e: InfluxException) { - logger.warn("Could not record the ${this@AbstractSlashCommand.info.name} command in InfluxDB. Reason: ${e.message ?: "Unknown"}") - } - } + if (!SlashCommandManager.isDevCommand(this@AbstractSlashCommand)) { + try { + CommandInfluxDatabase.recordCommand( + guild = event.guild, + command = this@AbstractSlashCommand, + executor = event.user + ) + } catch (e: InfluxException) { + logger.warn("Could not record the ${this@AbstractSlashCommand.info.name} command in InfluxDB. Reason: ${e.message ?: "Unknown"}") } } } @@ -309,12 +304,12 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand upsertCommand(this) } - protected suspend fun sendRandomMessage(event: SlashCommandInteractionEvent) { + protected fun sendRandomMessage(event: SlashCommandInteractionEvent) { if (SlashCommandManager.isMusicCommand(this) && event.channel.type.isMessage) RandomMessageManager().randomlySendMessage(event.channel as GuildMessageChannel) } - protected suspend fun checks(event: SlashCommandInteractionEvent): Boolean { + protected fun checks(event: SlashCommandInteractionEvent): Boolean { if (!nameCheck(event)) return false if (!guildCheck(event)) return false if (!event.isFromGuild) return true @@ -331,21 +326,21 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand if (!botDB.userHasViewedAlert(user.idLong) && latestAlert.isNotEmpty() && latestAlert.isNotBlank() && SlashCommandManager.isMusicCommand(this) ) { - val msg = event.channel.asGuildMessageChannel().sendMessageEmbeds( + event.channel.asGuildMessageChannel().sendMessageEmbeds( RobertifyEmbedUtils.embedMessage( event.guild, GeneralMessages.UNREAD_ALERT_MENTION, Pair("{user}", user.asMention) ).build() - ).await() - - val dedicatedChannelConfig = RequestChannelConfig(msg.guild) - if (dedicatedChannelConfig.isChannelSet()) if (dedicatedChannelConfig.getChannelId() == msg.channel - .idLong - ) msg.delete().queueAfter( - 10, TimeUnit.SECONDS, null, - ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE) - ) + ).queue { msg -> + val dedicatedChannelConfig = RequestChannelConfig(msg.guild) + if (dedicatedChannelConfig.isChannelSet()) if (dedicatedChannelConfig.getChannelId() == msg.channel + .idLong + ) msg.delete().queueAfter( + 10, TimeUnit.SECONDS, null, + ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE) + ) + } } } @@ -372,7 +367,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand info.name == event.name - protected open suspend fun guildCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun guildCheck(event: SlashCommandInteractionEvent): Boolean { if (info.isGuild) return true if (!event.isFromGuild && info.guildUseOnly) { event.replyEmbeds( @@ -389,7 +384,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand * @param event * @return True if the user is banned, false if otherwise. */ - protected open suspend fun banCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun banCheck(event: SlashCommandInteractionEvent): Boolean { val guild = event.guild ?: return true if (!GuildConfig(guild).isBannedUser(event.user.idLong)) return true event.replyEmbeds( @@ -411,7 +406,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand * @return True - If the command isn't a DJ command or the user is a DJ * False - If the command is a DJ command and the user isn't a DJ. */ - protected open suspend fun musicCommandDJCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun musicCommandDJCheck(event: SlashCommandInteractionEvent): Boolean { return predicateCheck(event) } @@ -423,14 +418,14 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand * @return True - If the command isn't a premium command or the user is a premium user * False - If the command is a premium command and the user isn't a premium user */ - protected open suspend fun premiumCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun premiumCheck(event: SlashCommandInteractionEvent): Boolean { if (!event.isFromGuild) return true if (!info.isPremium) return true val user = event.user return !(!GeneralUtils.checkPremium(event.guild!!, event) && user.idLong != 276778018440085505L) } - protected open suspend fun premiumBotCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun premiumBotCheck(event: SlashCommandInteractionEvent): Boolean { if (!Config.PREMIUM_BOT) return true val guild = event.guild ?: return true if (!GuildConfig(guild).isPremium()) { @@ -462,7 +457,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand * true will be returned. * False will be returned if and only if the command is DJ-only and the user is not a DJ. */ - protected open suspend fun djCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun djCheck(event: SlashCommandInteractionEvent): Boolean { if (!event.isFromGuild) return true val guild = event.guild!! val toggles = TogglesConfig(guild) @@ -492,7 +487,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand * true will be returned. * False will be returned if and only if the command is admin-only and the user is not an admin. */ - protected open suspend fun adminCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun adminCheck(event: SlashCommandInteractionEvent): Boolean { if (!event.isFromGuild) return true val guild = event.guild!! if (info.adminOnly @@ -512,7 +507,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand return true } - protected open suspend fun predicateCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun predicateCheck(event: SlashCommandInteractionEvent): Boolean { return if (info.checkPermission == null && info.requiredPermissions.isNotEmpty()) { if (!event.isFromGuild) true @@ -532,7 +527,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand if (GeneralUtils.isDeveloper(event.id)) true else info.checkPermission?.invoke(event) ?: true } - protected open suspend fun botPermsCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun botPermsCheck(event: SlashCommandInteractionEvent): Boolean { if (info.botRequiredPermissions.isEmpty()) return true val guild = event.guild ?: return true val self = guild.selfMember @@ -553,7 +548,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand return true } - protected open suspend fun botEmbedCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun botEmbedCheck(event: SlashCommandInteractionEvent): Boolean { val guild = event.guild ?: return true if (!guild.selfMember.hasPermission(event.guildChannel, Permission.MESSAGE_EMBED_LINKS)) { event.reply( @@ -566,7 +561,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand return true } - protected open suspend fun restrictedChannelCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun restrictedChannelCheck(event: SlashCommandInteractionEvent): Boolean { val guild = event.guild ?: return true val togglesConfig = TogglesConfig(guild) val config = RestrictedChannelsConfig(guild) @@ -594,7 +589,7 @@ abstract class AbstractSlashCommand protected constructor(val info: SlashCommand return true } - protected open suspend fun devCheck(event: SlashCommandInteractionEvent): Boolean { + protected open fun devCheck(event: SlashCommandInteractionEvent): Boolean { if (!nameCheck(event)) return false if (!info.developerOnly) return true if (!BotDBCache.instance.isDeveloper(event.user.idLong)) { diff --git a/src/main/kotlin/main/utils/database/mongodb/cache/redis/DatabaseRedisCache.kt b/src/main/kotlin/main/utils/database/mongodb/cache/redis/DatabaseRedisCache.kt index f6a7990c..6e0fabc8 100644 --- a/src/main/kotlin/main/utils/database/mongodb/cache/redis/DatabaseRedisCache.kt +++ b/src/main/kotlin/main/utils/database/mongodb/cache/redis/DatabaseRedisCache.kt @@ -14,45 +14,45 @@ abstract class DatabaseRedisCache protected constructor(cacheID: String, val mon fun init() = mongoDB.init() - suspend fun addToCache(identifier: String, obj: JSONObject) { + fun addToCache(identifier: String, obj: JSONObject) { val objectID = mongoDB.addDocument(obj) setex(identifier, 3600, obj.put("_id", objectID.value.toString()).toString()) } - open suspend fun updateCache(identifier: String, oldDoc: Document, document: Document) { + open fun updateCache(identifier: String, oldDoc: Document, document: Document) { del(identifier) setex(identifier, 3600, mongoDB.documentToJSON(document)) mongoDB.upsertDocument(oldDoc, document) } - override suspend fun updateCache(identifier: String, document: Document) { + override fun updateCache(identifier: String, document: Document) { del(identifier) setex(identifier, 3600, mongoDB.documentToJSON(document)) mongoDB.upsertDocument(doc = document) } - open suspend fun updateCacheNoDB(identifier: String, document: Document) { + open fun updateCacheNoDB(identifier: String, document: Document) { del(identifier) setex(identifier, 3600, mongoDB.documentToJSON(document)) } - open suspend fun updateCacheNoDB(identifier: String, json: JSONObject) { + open fun updateCacheNoDB(identifier: String, json: JSONObject) { del(identifier) setex(identifier, 3600, json.toString()) } - override suspend fun updateCache(identifier: String, `object`: JSONObject) { + override fun updateCache(identifier: String, `object`: JSONObject) { del(identifier) setex(identifier, 3600, `object`.toString()) mongoDB.upsertDocument(`object`) } - override suspend fun updateCacheObjects(objects: HashMap) { + override fun updateCacheObjects(objects: HashMap) { val documents = HashMap() objects.forEach { (key: String, `object`: JSONObject) -> documents[key] = Document.parse(`object`.toString()) @@ -60,7 +60,7 @@ abstract class DatabaseRedisCache protected constructor(cacheID: String, val mon updateCache(documents) } - override suspend fun updateCache(documents: HashMap) { + override fun updateCache(documents: HashMap) { for ((key, value) in documents) { del(key) setex(key, 3600, mongoDB.documentToJSON(value)) @@ -68,22 +68,22 @@ abstract class DatabaseRedisCache protected constructor(cacheID: String, val mon mongoDB.upsertManyDocuments(documents.values.stream().toList()) } - open suspend fun updateCache(obj: JSONObject, identifier: GenericJSONField, identifierValue: T) { + open fun updateCache(obj: JSONObject, identifier: GenericJSONField, identifierValue: T) { updateCache(obj, identifier.toString(), identifierValue) } - open suspend fun updateCache(obj: JSONObject, identifier: String, identifierValue: T) { + open fun updateCache(obj: JSONObject, identifier: String, identifierValue: T) { require(obj.has(identifier)) { "The JSON object must have the identifier passed!" } val document = mongoDB.findSpecificDocument(identifier, identifierValue) ?: throw NullPointerException("There was no document found with that identifier value!") updateCache(identifierValue.toString(), document, Document.parse(obj.toString())) } - override suspend fun getJSON(id: String): JSONObject? { + override fun getJSON(id: String): JSONObject? { return JSONObject(get(id)) } - override suspend fun getJSONByGuild(gid: String): JSONObject? { + override fun getJSONByGuild(gid: String): JSONObject? { return getJSON(gid) } @@ -99,7 +99,7 @@ abstract class DatabaseRedisCache protected constructor(cacheID: String, val mon return collectionObj } - override suspend fun getCache(id: String): JSONObject { + override fun getCache(id: String): JSONObject { return JSONObject(get(id)) } diff --git a/src/main/kotlin/main/utils/database/mongodb/cache/redis/RedisCache.kt b/src/main/kotlin/main/utils/database/mongodb/cache/redis/RedisCache.kt index b3e64a82..ec9f4ed0 100644 --- a/src/main/kotlin/main/utils/database/mongodb/cache/redis/RedisCache.kt +++ b/src/main/kotlin/main/utils/database/mongodb/cache/redis/RedisCache.kt @@ -14,9 +14,9 @@ abstract class RedisCache protected constructor(cacheID: String) { private val jedis = RedisDB.jedis } - protected val cacheID = "$cacheID#${Config.MONGO_DATABASE_NAME}#" + private val cacheID = "$cacheID#${Config.MONGO_DATABASE_NAME}#" - protected suspend fun hsetJSON(identifier: String, hash: HashMap) = coroutineScope { + protected fun hsetJSON(identifier: String, hash: HashMap) { val newHash = HashMap() hash.forEach { (key: String, `val`: JSONObject) -> newHash[key] = `val`.toString() @@ -25,96 +25,96 @@ abstract class RedisCache protected constructor(cacheID: String) { hset(identifier, newHash) } - protected suspend fun hset(identifier: String, hash: HashMap) = coroutineScope { + protected fun hset(identifier: String, hash: HashMap) { jedis.hset(cacheID + identifier, hash) } - protected suspend fun hset(hash: HashMap) { + protected fun hset(hash: HashMap) { hset(cacheID, hash) } - protected suspend fun hget(identifier: String, key: String): String? = coroutineScope { - return@coroutineScope jedis.hget(cacheID + identifier, key) + protected fun hget(identifier: String, key: String): String? { + return jedis.hget(cacheID + identifier, key) } - protected suspend fun hgetJSON(identifier: String, key: String): JSONObject { + protected fun hgetJSON(identifier: String, key: String): JSONObject { return JSONObject(hget(identifier, key)) } - protected suspend fun hgetAll(key: String): Map = coroutineScope { - return@coroutineScope jedis.hgetAll(key) + protected fun hgetAll(key: String): Map { + return jedis.hgetAll(key) } - protected suspend fun setex(identifier: String, seconds: Long, value: String): String = coroutineScope { - jedis.setex(cacheID + identifier, seconds, value) + protected fun setex(identifier: String, seconds: Long, value: String): String { + return jedis.setex(cacheID + identifier, seconds, value) } - protected open suspend fun set(identifier: String, value: String) { + protected open fun set(identifier: String, value: String) { jedis.set(cacheID + identifier, value) } - protected suspend fun set(value: String): String = coroutineScope { - jedis.set(cacheID, value) + protected fun set(value: String): String { + return jedis.set(cacheID, value) } - protected suspend fun setex(identifier: String, seconds: Long, value: JSONObject) { + protected fun setex(identifier: String, seconds: Long, value: JSONObject) { setex(identifier, seconds, value.toString()) } - protected suspend fun setex(identifier: Long, seconds: Long, value: JSONObject) { + protected fun setex(identifier: Long, seconds: Long, value: JSONObject) { setex(identifier.toString(), seconds, value.toString()) } - protected open suspend fun get(identifier: String): String? = coroutineScope { + protected open fun get(identifier: String): String? { val item = jedis.get(cacheID + identifier) - return@coroutineScope if (item == "nil") null else item + return if (item == "nil") null else item } - protected open suspend fun get(identifier: Long): String? { + protected open fun get(identifier: Long): String? { return get(identifier.toString()) } - protected suspend fun get(): String? = coroutineScope { - return@coroutineScope jedis.get(cacheID) + protected fun get(): String? { + return jedis.get(cacheID) } - protected suspend fun del(identifier: String): Long = coroutineScope { - return@coroutineScope jedis.del(cacheID + identifier) + protected fun del(identifier: String): Long { + return jedis.del(cacheID + identifier) } - protected suspend fun del(identifier: Long): Long { + protected fun del(identifier: Long): Long { return del(identifier.toString()) } - protected suspend fun del(): Long = coroutineScope { - return@coroutineScope jedis.del(cacheID) + protected fun del(): Long { + return jedis.del(cacheID) } - protected suspend fun exists(): Boolean = coroutineScope { - return@coroutineScope jedis.exists(cacheID) + protected fun exists(): Boolean { + return jedis.exists(cacheID) } - protected suspend fun exists(identifier: String): Boolean = coroutineScope { - return@coroutineScope jedis.exists(cacheID + identifier) + protected fun exists(identifier: String): Boolean { + return jedis.exists(cacheID + identifier) } - open suspend fun updateCache(identifier: String, document: Document) { + open fun updateCache(identifier: String, document: Document) { set(cacheID + identifier, document.toJson()) } - suspend fun updateCache(identifier: String, document: Document, expiration: Long) { + fun updateCache(identifier: String, document: Document, expiration: Long) { setex(cacheID + identifier, expiration, document.toJson()) } - open suspend fun updateCache(identifier: String, `object`: JSONObject) { + open fun updateCache(identifier: String, `object`: JSONObject) { set(cacheID + identifier, `object`.toString()) } - suspend fun updateCache(identifier: String, `object`: JSONObject, expiration: Long) { + fun updateCache(identifier: String, `object`: JSONObject, expiration: Long) { setex(cacheID + identifier, expiration, `object`.toString()) } - open suspend fun updateCacheObjects(objects: HashMap) { + open fun updateCacheObjects(objects: HashMap) { val documents = HashMap() objects.forEach { (key: String, `object`: JSONObject) -> documents[key] = Document.parse(`object`.toString()) @@ -122,29 +122,29 @@ abstract class RedisCache protected constructor(cacheID: String) { updateCache(documents) } - open suspend fun updateCache(documents: HashMap) { + open fun updateCache(documents: HashMap) { for ((key, value) in documents) jedis.setex(cacheID + key, 3600, value.toJson()) } - suspend fun removeFromCache(id: String) { + fun removeFromCache(id: String) { del(id) } - suspend fun getCacheJSON(identifier: String): JSONObject { + fun getCacheJSON(identifier: String): JSONObject { return JSONObject(get(identifier)) } - open suspend fun getJSON(id: String): JSONObject? { + open fun getJSON(id: String): JSONObject? { val source = get(id) ?: return null return JSONObject(source) } - open suspend fun getJSONByGuild(gid: String): JSONObject? { + open fun getJSONByGuild(gid: String): JSONObject? { return getJSON(gid) } - suspend fun getJSONByGuild(gid: Long): JSONObject? { + fun getJSONByGuild(gid: Long): JSONObject? { return getJSON(gid.toString()) } @@ -160,7 +160,7 @@ abstract class RedisCache protected constructor(cacheID: String) { return collectionObj } - open suspend fun getCache(id: String): JSONObject { + open fun getCache(id: String): JSONObject { return JSONObject(get(cacheID + id)) } diff --git a/src/main/kotlin/main/utils/database/mongodb/cache/redis/guild/GuildRedisCache.kt b/src/main/kotlin/main/utils/database/mongodb/cache/redis/guild/GuildRedisCache.kt index 6fe726b8..5a568d23 100644 --- a/src/main/kotlin/main/utils/database/mongodb/cache/redis/guild/GuildRedisCache.kt +++ b/src/main/kotlin/main/utils/database/mongodb/cache/redis/guild/GuildRedisCache.kt @@ -29,13 +29,13 @@ class GuildRedisCache private constructor() : DatabaseRedisCache("ROBERTIFY_GUIL } } - suspend fun updateGuild(guild: GuildDatabaseModel) { + fun updateGuild(guild: GuildDatabaseModel) { if (!guildHasInfo(guild.server_id)) loadGuild(guild.server_id) setex(guild.server_id, 3600, readyGuildObjForRedis(guild.toJsonObject())) getDB().updateGuild(guild) } - suspend fun updateGuild(gid: String, block: GuildDatabaseModel.() -> Unit) { + fun updateGuild(gid: String, block: GuildDatabaseModel.() -> Unit) { if (!guildHasInfo(gid)) loadGuild(gid) val guildModel = getGuildModel(gid)!! block(guildModel) @@ -50,7 +50,7 @@ class GuildRedisCache private constructor() : DatabaseRedisCache("ROBERTIFY_GUIL } } - suspend fun getGuildModel(gid: String): GuildDatabaseModel? { + fun getGuildModel(gid: String): GuildDatabaseModel? { if (!guildHasInfo(gid)) loadGuild(gid) val guildInfo = get(gid) ?: return null val json = correctGuildObj(JSONObject(guildInfo)).toString() @@ -234,19 +234,19 @@ class GuildRedisCache private constructor() : DatabaseRedisCache("ROBERTIFY_GUIL return obj } - suspend fun guildHasInfo(gid: Long): Boolean { + fun guildHasInfo(gid: Long): Boolean { return get(gid) != null } - suspend fun guildHasInfo(gid: String?): Boolean { + fun guildHasInfo(gid: String?): Boolean { return get(gid!!) != null } - suspend fun loadGuild(gid: Long) { + fun loadGuild(gid: Long) { loadGuild(gid.toString(), 0) } - suspend fun loadGuild(gid: String) { + fun loadGuild(gid: String) { loadGuild(gid, 0) } @@ -255,7 +255,7 @@ class GuildRedisCache private constructor() : DatabaseRedisCache("ROBERTIFY_GUIL * @param gid The ID of the guild * @param attempt The recursive attempt */ - private suspend fun loadGuild(gid: String, attempt: Int) { + private fun loadGuild(gid: String, attempt: Int) { var scopedAttempt = attempt logger.debug("Attempting to load guild with ID: {}", gid) try { @@ -283,11 +283,11 @@ class GuildRedisCache private constructor() : DatabaseRedisCache("ROBERTIFY_GUIL } } - suspend fun unloadGuild(gid: Long) { + fun unloadGuild(gid: Long) { del(gid) } - suspend fun loadAllGuilds() { + fun loadAllGuilds() { logger.debug("Attempting to load all guilds") collection.find().forEach { document: Document -> val jsonObject = readyGuildObjForRedis(JSONObject(document.toJson())) diff --git a/src/main/kotlin/main/utils/json/AbstractGuildConfig.kt b/src/main/kotlin/main/utils/json/AbstractGuildConfig.kt index fe5146d5..c6014641 100644 --- a/src/main/kotlin/main/utils/json/AbstractGuildConfig.kt +++ b/src/main/kotlin/main/utils/json/AbstractGuildConfig.kt @@ -21,17 +21,17 @@ abstract class AbstractGuildConfig protected constructor(private val guild: Guil } - abstract suspend fun update() + abstract fun update() - protected suspend fun getGuildModel(): GuildDatabaseModel { + protected fun getGuildModel(): GuildDatabaseModel { return cache.getGuildModel(guild.id)!! } - protected suspend fun guildHasInfo(): Boolean = cache.guildHasInfo(guild.idLong) + protected fun guildHasInfo(): Boolean = cache.guildHasInfo(guild.idLong) - protected suspend fun loadGuild() = cache.loadGuild(guild.idLong) + protected fun loadGuild() = cache.loadGuild(guild.idLong) - protected suspend fun unloadGuild() = cache.unloadGuild(guild.idLong) + protected fun unloadGuild() = cache.unloadGuild(guild.idLong) protected fun getDatabase(): GuildDB = cache.mongoDB as GuildDB } \ No newline at end of file diff --git a/src/main/kotlin/main/utils/json/autoplay/AutoPlayConfig.kt b/src/main/kotlin/main/utils/json/autoplay/AutoPlayConfig.kt index 0e45e9eb..47f0aa98 100644 --- a/src/main/kotlin/main/utils/json/autoplay/AutoPlayConfig.kt +++ b/src/main/kotlin/main/utils/json/autoplay/AutoPlayConfig.kt @@ -8,17 +8,17 @@ import java.util.* class AutoPlayConfig(private val guild: Guild) : AbstractGuildConfig(guild) { - suspend fun getStatus(): Boolean { + fun getStatus(): Boolean { return getGuildModel().autoplay ?: false } - suspend fun setStatus(status: Boolean) { + fun setStatus(status: Boolean) { cache.updateGuild(guild.id) { autoplay = status } } - override suspend fun update() { + override fun update() { val guildObject = getGuildModel().toJsonObject() if (!guildObject.has(Field.AUTOPLAY.name.lowercase(Locale.getDefault()))) guildObject.put(Field.AUTOPLAY.name.lowercase(), false) diff --git a/src/main/kotlin/main/utils/json/eightball/EightBallConfig.kt b/src/main/kotlin/main/utils/json/eightball/EightBallConfig.kt index 0d76af4b..25c36b08 100644 --- a/src/main/kotlin/main/utils/json/eightball/EightBallConfig.kt +++ b/src/main/kotlin/main/utils/json/eightball/EightBallConfig.kt @@ -1,16 +1,15 @@ package main.utils.json.eightball -import main.utils.database.mongodb.databases.GuildDB import main.utils.json.AbstractGuildConfig import net.dv8tion.jda.api.entities.Guild class EightBallConfig(private val guild: Guild) : AbstractGuildConfig(guild) { - suspend fun getResponses(): List { - return getGuildModel().eight_ball ?: emptyList() + fun getResponses(): List { + return getGuildModel().eight_ball } - suspend fun addResponse(response: String) { + fun addResponse(response: String) { cache.updateGuild(guild.id) { eight_ball { add(response) @@ -18,7 +17,7 @@ class EightBallConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun removeResponse(responseIndex: Int): String { + fun removeResponse(responseIndex: Int): String { var removed = getResponses()[responseIndex] cache.updateGuild(guild.id) { @@ -30,7 +29,7 @@ class EightBallConfig(private val guild: Guild) : AbstractGuildConfig(guild) { return removed } - suspend fun clearResponses() { + fun clearResponses() { cache.updateGuild(guild.id) { eight_ball { clear() @@ -38,7 +37,7 @@ class EightBallConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - override suspend fun update() { + override fun update() { // Nothing } } \ No newline at end of file diff --git a/src/main/kotlin/main/utils/json/guildconfig/GuildConfig.kt b/src/main/kotlin/main/utils/json/guildconfig/GuildConfig.kt index d247d643..2f3426a6 100644 --- a/src/main/kotlin/main/utils/json/guildconfig/GuildConfig.kt +++ b/src/main/kotlin/main/utils/json/guildconfig/GuildConfig.kt @@ -19,23 +19,23 @@ class GuildConfig(private val guild: Guild) : AbstractGuildConfig(guild) { private val logger = LoggerFactory.getLogger(Companion::class.java) } - suspend fun getTwentyFourSevenMode(): Boolean { + fun getTwentyFourSevenMode(): Boolean { val guildModel = getGuildModel() return guildModel.twenty_four_seven_mode } - suspend fun setTwentyFourSevenMode(value: Boolean) { + fun setTwentyFourSevenMode(value: Boolean) { cache.updateGuild(guild.id) { twenty_four_seven_mode = value } } - suspend fun addGuild() { + fun addGuild() { require(guildHasInfo()) { "This guild is already added!" } getDatabase().addGuild(guild.idLong) } - suspend fun removeGuild() { + fun removeGuild() { getDatabase().removeGuild(guild.idLong) if (!guildHasInfo()) logger.warn( "There is no information for guild with ID {} in the cache.", @@ -43,11 +43,11 @@ class GuildConfig(private val guild: Guild) : AbstractGuildConfig(guild) { ) else unloadGuild() } - suspend fun setFields(block: GuildDatabaseModel.() -> Unit) { + fun setFields(block: GuildDatabaseModel.() -> Unit) { cache.updateGuild(guild.id, block) } - private suspend fun getBannedUsers(): List { + private fun getBannedUsers(): List { return getGuildModel().banned_users .map { user -> BannedUser( @@ -59,14 +59,14 @@ class GuildConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun getBannedUsersWithUnbanTimes(): HashMap { + fun getBannedUsersWithUnbanTimes(): HashMap { val bannedUsers = getBannedUsers() val ret = HashMap() for (bannedUser in bannedUsers) ret[bannedUser.user] = bannedUser.bannedUntil return ret } - suspend fun banUser(uid: Long, modId: Long, bannedAt: Long, bannedUntil: Long) { + fun banUser(uid: Long, modId: Long, bannedAt: Long, bannedUntil: Long) { require(!isBannedUser(uid)) { "This user is already banned!" } setFields { @@ -81,7 +81,7 @@ class GuildConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun unbanUser(uid: Long) { + fun unbanUser(uid: Long) { require(isBannedUser(uid)) { "This user isn't banned!" } setFields { @@ -89,14 +89,14 @@ class GuildConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun getTimeUntilUnban(uid: Long): Long { + fun getTimeUntilUnban(uid: Long): Long { require(isBannedUser(uid)) { "This user isn't banned!" } val (_, _, bannedAt, bannedUntil) = getBannedUsers() .filter { user: BannedUser -> user.user == uid }[0] return bannedUntil - bannedAt } - suspend fun isBannedUser(uid: Long): Boolean { + fun isBannedUser(uid: Long): Boolean { return getBannedUsers() .any { user: BannedUser -> user.user == uid } } @@ -106,7 +106,7 @@ class GuildConfig(private val guild: Guild) : AbstractGuildConfig(guild) { // return Robertify.getRobertifyAPI().guildIsPremium(guild.idLong); } - override suspend fun update() { + override fun update() { // Nothing } diff --git a/src/main/kotlin/main/utils/json/locale/LocaleConfig.kt b/src/main/kotlin/main/utils/json/locale/LocaleConfig.kt index 6fe7c184..919c6834 100644 --- a/src/main/kotlin/main/utils/json/locale/LocaleConfig.kt +++ b/src/main/kotlin/main/utils/json/locale/LocaleConfig.kt @@ -6,17 +6,17 @@ import net.dv8tion.jda.api.entities.Guild class LocaleConfig(private val guild: Guild) : AbstractGuildConfig(guild) { - suspend fun getLocale(): RobertifyLocale { + fun getLocale(): RobertifyLocale { return RobertifyLocale.parse(getGuildModel().locale) } - suspend fun setLocale(locale: RobertifyLocale) { + fun setLocale(locale: RobertifyLocale) { cache.updateGuild(guild.id) { this.locale = locale.name.lowercase() } } - override suspend fun update() { + override fun update() { TODO("Not yet implemented") } diff --git a/src/main/kotlin/main/utils/json/logs/LogConfig.kt b/src/main/kotlin/main/utils/json/logs/LogConfig.kt index 0ae520a8..49268e5f 100644 --- a/src/main/kotlin/main/utils/json/logs/LogConfig.kt +++ b/src/main/kotlin/main/utils/json/logs/LogConfig.kt @@ -11,36 +11,36 @@ import java.util.* class LogConfig(private val guild: Guild) : AbstractGuildConfig(guild) { - private suspend fun getChannelId(): Long? { + private fun getChannelId(): Long? { if (!channelIsSet()) throw NullPointerException("There is no channel for this guild! (ID=${guild.id})") return getGuildModel().log_channel } - suspend fun setChannelId(cid: Long) { + fun setChannelId(cid: Long) { cache.updateGuild(guild.id) { log_channel = cid } } - suspend fun getChannel(): TextChannel? { + fun getChannel(): TextChannel? { val channelId = getChannelId() return channelId?.let { Robertify.shardManager.getTextChannelById(it) } } - suspend fun channelIsSet(): Boolean { + fun channelIsSet(): Boolean { return getGuildModel().log_channel?.let { it != -1L } ?: false } - suspend fun removeChannel() { + fun removeChannel() { cache.updateGuild(guild.id) { log_channel = -1L } } - override suspend fun update() { + override fun update() { val guildObject: JSONObject = getGuildModel().toJsonObject() if (!guildObject.has(Field.LOG_CHANNEL.name.lowercase(Locale.getDefault()))) guildObject.put( Field.LOG_CHANNEL.name.lowercase( diff --git a/src/main/kotlin/main/utils/json/logs/LogUtilsKt.kt b/src/main/kotlin/main/utils/json/logs/LogUtilsKt.kt index 597427af..4912d4f1 100644 --- a/src/main/kotlin/main/utils/json/logs/LogUtilsKt.kt +++ b/src/main/kotlin/main/utils/json/logs/LogUtilsKt.kt @@ -14,7 +14,7 @@ import java.time.Instant class LogUtilsKt(private val guild: Guild) { private val config: LogConfig = LogConfig(guild) - suspend fun sendLog(type: LogType, message: String) { + fun sendLog(type: LogType, message: String) { if (!config.channelIsSet()) return if (!TogglesConfig(guild).getLogToggle(type)) return val channel = config.getChannel() @@ -28,7 +28,7 @@ class LogUtilsKt(private val guild: Guild) { ).queue() } - suspend fun sendLog(type: LogType, message: LocaleMessage) { + fun sendLog(type: LogType, message: LocaleMessage) { if (!config.channelIsSet()) return if (!TogglesConfig(guild).getLogToggle(type)) return val localeManager = LocaleManager[guild] @@ -44,7 +44,7 @@ class LogUtilsKt(private val guild: Guild) { } @SafeVarargs - suspend fun sendLog(type: LogType, message: LocaleMessage, vararg placeholders: Pair) { + fun sendLog(type: LogType, message: LocaleMessage, vararg placeholders: Pair) { if (!config.channelIsSet()) return if (!TogglesConfig(guild).getLogToggle(type)) return val localeManager = LocaleManager[guild] @@ -62,17 +62,18 @@ class LogUtilsKt(private val guild: Guild) { } } - suspend fun createChannel() { + fun createChannel() { if (config.channelIsSet()) config.removeChannel() - val channel = guild.createTextChannel("robertify-logs") + guild.createTextChannel("robertify-logs") .addPermissionOverride(guild.publicRole, emptyList(), listOf(Permission.VIEW_CHANNEL)) .addPermissionOverride( guild.selfMember, listOf(Permission.VIEW_CHANNEL, Permission.MANAGE_CHANNEL, Permission.MESSAGE_SEND), emptyList() ) - .await() - config.setChannelId(channel.idLong) + .queue { channel -> + config.setChannelId(channel.idLong) + } } } \ No newline at end of file diff --git a/src/main/kotlin/main/utils/json/permissions/PermissionsConfig.kt b/src/main/kotlin/main/utils/json/permissions/PermissionsConfig.kt index 7d1a20a9..8e8a7bf0 100644 --- a/src/main/kotlin/main/utils/json/permissions/PermissionsConfig.kt +++ b/src/main/kotlin/main/utils/json/permissions/PermissionsConfig.kt @@ -15,7 +15,7 @@ import java.io.IOException import java.util.* class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { - suspend fun addPermissionToUser(userID: Long, p: RobertifyPermission) { + fun addPermissionToUser(userID: Long, p: RobertifyPermission) { var obj = getGuildModel().toJsonObject() var usersObj = obj.getJSONObject(GuildDB.Field.PERMISSIONS_OBJECT.toString()) .getJSONObject(PermissionConfigField.USER_PERMISSIONS.toString()) @@ -39,7 +39,7 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { cache.updateCache(obj, GuildDB.Field.GUILD_ID, guild.idLong) } - suspend fun userHasPermission(userID: Long, p: RobertifyPermission): Boolean { + fun userHasPermission(userID: Long, p: RobertifyPermission): Boolean { val userObj = getGuildModel().toJsonObject() .getJSONObject(GuildDB.Field.PERMISSIONS_OBJECT.toString()) .getJSONObject(PermissionConfigField.USER_PERMISSIONS.toString()) @@ -47,7 +47,7 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { .contains(p.code) } - suspend fun removePermissionFromUser(userID: Long, p: RobertifyPermission) { + fun removePermissionFromUser(userID: Long, p: RobertifyPermission) { require(userHasPermission(userID, p)) { "User with id \"$userID\" doesn't have ${p.name}" } val obj = getGuildModel().toJsonObject() val usersObj = obj.getJSONObject(GuildDB.Field.PERMISSIONS_OBJECT.toString()) @@ -59,7 +59,7 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } @Throws(IllegalAccessException::class, IOException::class) - suspend fun removeRoleFromPermission(rid: Long, p: RobertifyPermission) { + fun removeRoleFromPermission(rid: Long, p: RobertifyPermission) { if (!getRolesForPermission(p).contains(rid)) throw IllegalAccessException("The role $rid doesn't have access to PermissionKt with code ${p.code}") val obj = getGuildModel().toJsonObject() val permArr = obj.getJSONObject(GuildDB.Field.PERMISSIONS_OBJECT.toString()) @@ -69,7 +69,7 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } @Throws(IllegalAccessException::class) - suspend fun addRoleToPermission(rid: Long, p: RobertifyPermission) { + fun addRoleToPermission(rid: Long, p: RobertifyPermission) { if (getRolesForPermission(p).contains(rid)) throw IllegalAccessException("The role $rid already has access to PermissionKt with code ${p.code}") val obj = getGuildModel().toJsonObject() val permArr = obj.getJSONObject(GuildDB.Field.PERMISSIONS_OBJECT.toString()) @@ -78,7 +78,7 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { cache.updateCache(obj, GuildDB.Field.GUILD_ID, guild.idLong) } - suspend fun getRolesForPermission(p: RobertifyPermission): List { + fun getRolesForPermission(p: RobertifyPermission): List { val ret: MutableList = ArrayList() val obj = getGuildModel().toJsonObject() .getJSONObject(GuildDB.Field.PERMISSIONS_OBJECT.toString()) @@ -95,7 +95,7 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { return ret } - suspend fun getRolesForPermission(p: String): List { + fun getRolesForPermission(p: String): List { if (!RobertifyPermission.permissions.contains(p.uppercase(Locale.getDefault()))) throw NullPointerException("There is no enum with the name \"$p\"") @@ -106,7 +106,7 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { return getRolesForPermission(RobertifyPermission.parse(code)) } - suspend fun getUsersForPermission(p: RobertifyPermission): List { + fun getUsersForPermission(p: RobertifyPermission): List { val code = p.code val ret: MutableList = ArrayList() return try { @@ -126,13 +126,13 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun getUsersForPermission(p: String): List { + fun getUsersForPermission(p: String): List { if (!RobertifyPermission.permissions.contains(p.uppercase(Locale.getDefault()))) throw NullPointerException("There is no enum with the name \"$p\"") return getUsersForPermission(RobertifyPermission.valueOf(p.uppercase())) } - suspend fun getPermissionsForRoles(rid: Long): List { + fun getPermissionsForRoles(rid: Long): List { val codes: MutableList = ArrayList() val obj = getGuildModel().toJsonObject() val permObj = obj.getJSONObject(GuildDB.Field.PERMISSIONS_OBJECT.toString()) @@ -155,7 +155,7 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { return codes } - suspend fun getPermissionsForUser(uid: Long): List { + fun getPermissionsForUser(uid: Long): List { val codes: MutableList = ArrayList() val obj = getGuildModel().toJsonObject() .getJSONObject(GuildDB.Field.PERMISSIONS_OBJECT.toString()) @@ -169,7 +169,7 @@ class PermissionsConfig(private val guild: Guild) : AbstractGuildConfig(guild) { return codes } - override suspend fun update() { + override fun update() { if (!guildHasInfo()) loadGuild() val cacheArr = GuildDBCache.ins.getCache() val obj = cacheArr.getJSONObject(getIndexOfObjectInArray(cacheArr, GuildDB.Field.GUILD_ID, guild.idLong)) diff --git a/src/main/kotlin/main/utils/json/reminders/RemindersConfig.kt b/src/main/kotlin/main/utils/json/reminders/RemindersConfig.kt index 942b9740..d5be7858 100644 --- a/src/main/kotlin/main/utils/json/reminders/RemindersConfig.kt +++ b/src/main/kotlin/main/utils/json/reminders/RemindersConfig.kt @@ -1,18 +1,14 @@ package main.utils.json.reminders import dev.minn.jda.ktx.util.SLF4J -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch import kotlinx.serialization.json.Json import main.utils.database.mongodb.cache.redis.guild.ReminderModel import main.utils.database.mongodb.cache.redis.guild.ReminderUserModel import main.utils.json.AbstractGuildConfig import main.utils.json.GenericJSONField -import main.utils.json.getIndexOfObjectInArray import main.utils.json.reminders.scheduler.ReminderScheduler import net.dv8tion.jda.api.entities.Guild import org.json.JSONArray -import org.json.JSONException import org.json.JSONObject import java.util.* @@ -40,7 +36,7 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { ) } - suspend fun addUser(uid: Long) { + fun addUser(uid: Long) { if (userExists(uid)) return cache.updateGuild(guild.id) { reminders { @@ -54,7 +50,7 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun addReminder(uid: Long, reminder: String, channelID: Long, reminderTime: Long, timeZone: String?) { + fun addReminder(uid: Long, reminder: String, channelID: Long, reminderTime: Long, timeZone: String?) { if (!userExists(uid)) addUser(uid) cache.updateGuild(guild.id) { @@ -72,7 +68,7 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun removeReminder(uid: Long, id: Int) { + fun removeReminder(uid: Long, id: Int) { if (!userHasReminders(uid)) throw NullPointerException("This user doesn't have any reminders in this guild!") @@ -86,7 +82,7 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun clearReminders(uid: Long) { + fun clearReminders(uid: Long) { if (!userHasReminders(uid) || getReminders(uid).isNullOrEmpty()) throw NullPointerException("This user doesn't have any reminders in this guild!") @@ -104,7 +100,7 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun editReminderChannel(uid: Long, id: Int, channelID: Long) { + fun editReminderChannel(uid: Long, id: Int, channelID: Long) { if (!userExists(uid)) throw NullPointerException("This user doesn't have any reminders to edit!") @@ -116,7 +112,7 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun editReminderTime(uid: Long, id: Int, time: Long) { + fun editReminderTime(uid: Long, id: Int, time: Long) { if (!userExists(uid)) throw NullPointerException("This user doesn't have any reminders to edit!") @@ -128,15 +124,15 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun banUser(uid: Long) { + fun banUser(uid: Long) { setBanState(uid, true) } - suspend fun unbanUser(uid: Long) { + fun unbanUser(uid: Long) { setBanState(uid, false) } - private suspend fun setBanState(uid: Long, state: Boolean) { + private fun setBanState(uid: Long, state: Boolean) { if (state) check(!userIsBanned(uid)) { "This user is already banned!" } else check(userIsBanned(uid)) { "This user is not banned!" } @@ -149,25 +145,22 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun userIsBanned(uid: Long): Boolean { + fun userIsBanned(uid: Long): Boolean { if (!userExists(uid)) addUser(uid) return getUser(uid)!!.isBanned } - suspend fun userHasReminders(uid: Long): Boolean { + fun userHasReminders(uid: Long): Boolean { return if (!userExists(uid)) false else getReminders(uid) != null } - suspend fun getReminders(uid: Long): List? = + fun getReminders(uid: Long): List? = Collections.unmodifiableList(getUser(uid)!!.reminders) - suspend fun getUser(uid: Long): ReminderUser? { - val remindersObj = getGuildModel().reminders ?: run { - update() - getGuildModel().reminders!! - } + fun getUser(uid: Long): ReminderUser? { + val remindersObj = getGuildModel().reminders val user = remindersObj.users.find { user -> user.user_id == uid } val reminders = user?.user_reminders?.mapIndexed { i, reminder -> @@ -191,8 +184,8 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { else null } - private suspend fun getAllGuildUsers(): List { - val users = getGuildModel().reminders?.users ?: return emptyList() + private fun getAllGuildUsers(): List { + val users = getGuildModel().reminders.users return users.map { user -> val reminders = user.user_reminders.mapIndexed { i, reminder -> Reminder( @@ -213,10 +206,10 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - private suspend fun guildHasReminders(): Boolean = + private fun guildHasReminders(): Boolean = getAllGuildUsers().any { user -> user.reminders.isNotEmpty() } - suspend fun banChannel(cid: Long) { + fun banChannel(cid: Long) { check(!channelIsBanned(cid)) { "This channel is already banned!" } cache.updateGuild(guild.id) { reminders { @@ -225,7 +218,7 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun unbanChannel(cid: Long) { + fun unbanChannel(cid: Long) { check(channelIsBanned(cid)) { "This channel is not banned!" } cache.updateGuild(guild.id) { reminders { @@ -234,36 +227,31 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun channelIsBanned(cid: Long): Boolean { - val reminders = getGuildModel().reminders ?: run { - update() - return false - } - + fun channelIsBanned(cid: Long): Boolean { + val reminders = getGuildModel().reminders return reminders.banned_channels.contains(cid) } - private suspend fun userExists(uid: Long): Boolean = + private fun userExists(uid: Long): Boolean = getUser(uid) != null - suspend fun scheduleReminders() = coroutineScope { - launch { - logger.debug("Attempting to schedule guild reminders for ${guild.name}") - val scheduler = ReminderScheduler(guild) + fun scheduleReminders() { + logger.debug("Attempting to schedule guild reminders for ${guild.name}") + val scheduler = ReminderScheduler(guild) - if (!guildHasReminders()) { - logger.debug("${guild.name} didn't have any reminders to schedule.") - return@launch - } + if (!guildHasReminders()) { + logger.debug("${guild.name} didn't have any reminders to schedule.") + return + } - val allGuildUsers = getAllGuildUsers() - allGuildUsers.forEach { user -> - val reminders = user.reminders + val allGuildUsers = getAllGuildUsers() + allGuildUsers.forEach { user -> + val reminders = user.reminders - logger.debug("Attempting to schedule reminder(s) for ${user.id} in ${guild.name}") - reminders.forEach { reminder -> - logger.debug( - """ + logger.debug("Attempting to schedule reminder(s) for ${user.id} in ${guild.name}") + reminders.forEach { reminder -> + logger.debug( + """ Scheduling reminder with information: User Id: ${user.id} Channel Id: ${reminder.channelId} @@ -272,40 +260,37 @@ class RemindersConfig(private val guild: Guild) : AbstractGuildConfig(guild) { Reminder: ${reminder.reminder} Reminder Id: ${reminder.id} """.trimIndent() - ) - scheduler.scheduleReminder( - user = user.id, - destination = reminder.channelId, - hour = reminder.hour, - minute = reminder.minute, - reminder = reminder.reminder, - reminderId = reminder.id, - timeZone = reminder.timezone.id - ) - } - logger.debug("Scheduled all ${reminders.size} reminder(s) for ${user.id} in ${guild.name}") + ) + scheduler.scheduleReminder( + user = user.id, + destination = reminder.channelId, + hour = reminder.hour, + minute = reminder.minute, + reminder = reminder.reminder, + reminderId = reminder.id, + timeZone = reminder.timezone.id + ) } + logger.debug("Scheduled all ${reminders.size} reminder(s) for ${user.id} in ${guild.name}") } } - suspend fun unscheduleReminders() = coroutineScope { - launch { - val scheduler = ReminderScheduler(guild) + fun unscheduleReminders() { + val scheduler = ReminderScheduler(guild) - if (!guildHasReminders()) - return@launch + if (!guildHasReminders()) + return - val allUsers = getAllGuildUsers() - allUsers.forEach { user -> - val reminders = user.reminders - reminders.forEach { reminder -> - scheduler.removeReminder(user.id, reminder.id) - } + val allUsers = getAllGuildUsers() + allUsers.forEach { user -> + val reminders = user.reminders + reminders.forEach { reminder -> + scheduler.removeReminder(user.id, reminder.id) } } } - override suspend fun update() { + override fun update() { val guildObject = getGuildModel().toJsonObject() if (!guildObject.has(Fields.REMINDERS.toString())) { val reminderObj = JSONObject() diff --git a/src/main/kotlin/main/utils/json/requestchannel/RequestChannelConfig.kt b/src/main/kotlin/main/utils/json/requestchannel/RequestChannelConfig.kt index cff37a1f..bddc7417 100644 --- a/src/main/kotlin/main/utils/json/requestchannel/RequestChannelConfig.kt +++ b/src/main/kotlin/main/utils/json/requestchannel/RequestChannelConfig.kt @@ -1,5 +1,6 @@ package main.utils.json.requestchannel +import dev.arbjerg.lavalink.protocol.v4.ifPresent import dev.minn.jda.ktx.coroutines.await import kotlinx.coroutines.* import kotlinx.serialization.json.Json @@ -15,7 +16,6 @@ import main.utils.RobertifyEmbedUtils import main.utils.component.interactions.selectionmenu.StringSelectMenuOption import main.utils.component.interactions.selectionmenu.StringSelectionMenuBuilder import main.utils.database.mongodb.cache.redis.guild.RequestChannelConfigModel -import main.utils.database.mongodb.cache.redis.guild.RequestChannelConfigModelOptional import main.utils.database.mongodb.cache.redis.guild.RequestChannelModel import main.utils.database.mongodb.databases.GuildDB import main.utils.json.AbstractGuildConfig @@ -45,6 +45,7 @@ import net.dv8tion.jda.api.sharding.ShardManager import org.json.JSONObject import org.slf4j.LoggerFactory import java.util.* +import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit class RequestChannelConfig(private val guild: Guild, private val shardManager: ShardManager = Robertify.shardManager) : @@ -53,27 +54,28 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S companion object { private val logger = LoggerFactory.getLogger(Companion::class.java) - suspend fun updateAllButtons() { + fun updateAllButtons() { for (g: Guild in Robertify.shardManager.guilds) { val config = RequestChannelConfig(g) if (!config.isChannelSet()) continue - val msg: Message = config.getMessageRequest()?.await() ?: continue - config.buttonUpdateRequest(msg).queue( - null, - ErrorHandler() - .handle( - ErrorResponse.MISSING_PERMISSIONS - ) { - logger.warn( - "Couldn't update buttons in {}", - g.name - ) - } - ) + config.getMessageRequest()?.queue { msg -> + config.buttonUpdateRequest(msg).queue( + null, + ErrorHandler() + .handle( + ErrorResponse.MISSING_PERMISSIONS + ) { + logger.warn( + "Couldn't update buttons in {}", + g.name + ) + } + ) + } } } - suspend fun updateAllTopics() { + fun updateAllTopics() { for (g: Guild in Robertify.shardManager.guilds) { val config = RequestChannelConfig(g) if (!config.isChannelSet()) continue @@ -83,7 +85,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } } - suspend fun getMessageId(): Long { + fun getMessageId(): Long { if (!isChannelSet()) throw IllegalArgumentException( shardManager.getGuildById(guild.idLong) ?.name + "(" + guild.idLong + ") doesn't have a channel set" @@ -92,7 +94,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S return getGuildModel().dedicated_channel!!.message_id ?: -1 } - suspend fun setMessageId(id: Long) { + fun setMessageId(id: Long) { cache.updateGuild(guild.id) { dedicated_channel { message_id = id @@ -100,7 +102,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } } - suspend fun getChannelId(): Long { + fun getChannelId(): Long { if (!isChannelSet()) throw IllegalArgumentException( shardManager.getGuildById(guild.idLong) ?.name + "(" + guild.idLong + ") doesn't have a channel set" @@ -109,7 +111,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S return getGuildModel().dedicated_channel!!.channel_id ?: -1 } - suspend fun setChannelId(id: Long) { + fun setChannelId(id: Long) { cache.updateGuild(guild.id) { dedicated_channel { channel_id = id @@ -117,11 +119,11 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } } - suspend fun getOriginalAnnouncementToggle(): Boolean { + fun getOriginalAnnouncementToggle(): Boolean { return getGuildModel().dedicated_channel?.og_announcement_toggle ?: true } - suspend fun setOriginalAnnouncementToggle(value: Boolean) { + fun setOriginalAnnouncementToggle(value: Boolean) { cache.updateGuild(guild.id) { dedicated_channel { og_announcement_toggle = value @@ -129,10 +131,10 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } } - suspend fun getTextChannel(): TextChannel? = + fun getTextChannel(): TextChannel? = shardManager.getTextChannelById(getChannelId()) - suspend fun getMessageRequest(): RestAction? = try { + fun getMessageRequest(): RestAction? = try { getTextChannel()?.retrieveMessageById(getMessageId()) } catch (e: InsufficientPermissionException) { val channel: GuildMessageChannel? = RobertifyAudioManager @@ -151,7 +153,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S val config: ChannelConfig get() = ChannelConfig(this) - suspend fun setChannelAndMessage(cid: Long, mid: Long) { + fun setChannelAndMessage(cid: Long, mid: Long) { cache.updateGuild(guild.id) { this.dedicated_channel = RequestChannelModel( mid, @@ -162,7 +164,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } } - suspend fun removeChannel() { + fun removeChannel() { if (!isChannelSet()) throw IllegalArgumentException( "${shardManager.getGuildById(guild.idLong)?.name} (${guild.idLong}) doesn't have a request channel set." @@ -183,128 +185,132 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } } - suspend fun isChannelSet(): Boolean { + fun isChannelSet(): Boolean { val obj = getGuildModel().dedicated_channel return obj.channel_id != -1L } - suspend fun isRequestChannel(channel: GuildMessageChannel): Boolean = when { + fun isRequestChannel(channel: GuildMessageChannel): Boolean = when { !isChannelSet() -> false else -> getChannelId() == channel.idLong } - suspend fun updateMessage(): Unit = coroutineScope { + fun updateMessage() { logger.debug("Channel set in ${guild.name} (${guild.idLong}): ${isChannelSet()}") - if (!isChannelSet()) return@coroutineScope + if (!isChannelSet()) return - val msgRequest: RestAction = getMessageRequest() ?: return@coroutineScope + val msgRequest: RestAction = getMessageRequest() ?: return val musicManager = RobertifyAudioManager[guild] - val audioPlayer = musicManager.player - val playingTrack = audioPlayer.playingTrack - val queueHandler = musicManager.scheduler.queueHandler - val queueAsList = ArrayList(queueHandler.contents) - - val theme = ThemesConfig(guild).getTheme() - val localeManager = LocaleManager[guild] - val eb = EmbedBuilder() - - if (playingTrack == null) { - eb.setColor(theme.color) - eb.setTitle(localeManager.getMessage(DedicatedChannelMessages.DEDICATED_CHANNEL_NOTHING_PLAYING)) - eb.setImage(theme.idleBanner) - val scheduler = musicManager.scheduler - val announcementChannel: GuildMessageChannel? = scheduler.announcementChannel - try { - val msg = msgRequest.await() - msg.editMessage(localeManager.getMessage(DedicatedChannelMessages.DEDICATED_CHANNEL_QUEUE_NOTHING_PLAYING)) - .setEmbeds(eb.build()) - .await() - } catch (e: InsufficientPermissionException) { - if (e.message!!.contains("MESSAGE_SEND")) sendEditErrorMessage(announcementChannel) - } catch (e: ErrorResponseException) { - when (e.errorResponse) { - ErrorResponse.MISSING_PERMISSIONS -> sendEditErrorMessage(announcementChannel) - ErrorResponse.UNKNOWN_MESSAGE -> removeChannel() - else -> {} + + musicManager.usePlayer { audioPlayer -> + val playingTrack = audioPlayer?.track + val queueHandler = musicManager.scheduler.queueHandler + val queueAsList = ArrayList(queueHandler.contents) + + val theme = ThemesConfig(guild).getTheme() + val localeManager = LocaleManager[guild] + val eb = EmbedBuilder() + + if (playingTrack == null) { + eb.setColor(theme.color) + eb.setTitle(localeManager.getMessage(DedicatedChannelMessages.DEDICATED_CHANNEL_NOTHING_PLAYING)) + eb.setImage(theme.idleBanner) + val scheduler = musicManager.scheduler + val announcementChannel: GuildMessageChannel? = scheduler.announcementChannel + try { + msgRequest.queue { msg -> + msg.editMessage(localeManager.getMessage(DedicatedChannelMessages.DEDICATED_CHANNEL_QUEUE_NOTHING_PLAYING)) + .setEmbeds(eb.build()) + .queue() + } + } catch (e: InsufficientPermissionException) { + if (e.message!!.contains("MESSAGE_SEND")) sendEditErrorMessage(announcementChannel) + } catch (e: ErrorResponseException) { + when (e.errorResponse) { + ErrorResponse.MISSING_PERMISSIONS -> sendEditErrorMessage(announcementChannel) + ErrorResponse.UNKNOWN_MESSAGE -> removeChannel() + else -> {} + } } - } - } else { - eb.setColor(theme.color) - eb.setTitle( - localeManager.getMessage( - DedicatedChannelMessages.DEDICATED_CHANNEL_PLAYING_EMBED_TITLE, - Pair( - "{title}", - playingTrack.title - ), - Pair( - "{author}", - playingTrack.author - ), - - Pair( - "{duration}", - GeneralUtils.formatTime(playingTrack.length) + } else { + eb.setColor(theme.color) + eb.setTitle( + localeManager.getMessage( + DedicatedChannelMessages.DEDICATED_CHANNEL_PLAYING_EMBED_TITLE, + Pair( + "{title}", + playingTrack.title + ), + Pair( + "{author}", + playingTrack.author + ), + + Pair( + "{duration}", + GeneralUtils.formatTime(playingTrack.length) + ) ) ) - ) - val requester: String = musicManager.scheduler.getRequesterAsMention(playingTrack) - eb.setDescription( - localeManager.getMessage( - NowPlayingMessages.NP_ANNOUNCEMENT_REQUESTER, - Pair("{requester}", requester) + val requester: String = musicManager.scheduler.getRequesterAsMention(playingTrack) + eb.setDescription( + localeManager.getMessage( + NowPlayingMessages.NP_ANNOUNCEMENT_REQUESTER, + Pair("{requester}", requester) + ) ) - ) - eb.setImage(playingTrack.artworkUrl ?: theme.nowPlayingBanner) - eb.setFooter( - localeManager.getMessage( - DedicatedChannelMessages.DEDICATED_CHANNEL_PLAYING_EMBED_FOOTER, - Pair( - "{numSongs}", - queueAsList.size.toString() - ), - Pair( - "{volume}", - ((audioPlayer.filters.volume?.times(100) ?: 100).toInt()).toString() + eb.setImage(playingTrack.artworkUrl ?: theme.nowPlayingBanner) + eb.setFooter( + localeManager.getMessage( + DedicatedChannelMessages.DEDICATED_CHANNEL_PLAYING_EMBED_FOOTER, + Pair( + "{numSongs}", + queueAsList.size.toString() + ), + Pair( + "{volume}", + ((audioPlayer.filters.volume.ifPresent { it.times(100) } ?: 100).toInt()).toString() + ) ) ) - ) - val nextTenSongs: StringBuilder = StringBuilder() - nextTenSongs.append("```") - if (queueAsList.size > 10) { - var index = 1 - for (track in queueAsList.subList( - 0, - 10 - )) nextTenSongs.append(index++).append(". → ").append(track.title) - .append(" - ").append(track.author) - .append(" [").append(GeneralUtils.formatTime(track.length)) - .append("]\n") - } else { - if (queueHandler.isEmpty) nextTenSongs.append(localeManager.getMessage(DedicatedChannelMessages.DEDICATED_CHANNEL_QUEUE_NO_SONGS)) else { + val nextTenSongs: StringBuilder = StringBuilder() + nextTenSongs.append("```") + if (queueAsList.size > 10) { var index = 1 - for (track in queueAsList) nextTenSongs.append( - index++ - ).append(". → ").append(track.title).append(" - ").append(track.author) + for (track in queueAsList.subList( + 0, + 10 + )) nextTenSongs.append(index++).append(". → ").append(track.info.title) + .append(" - ").append(track.info.author) .append(" [").append(GeneralUtils.formatTime(track.length)) .append("]\n") + } else { + if (queueHandler.isEmpty) nextTenSongs.append(localeManager.getMessage(DedicatedChannelMessages.DEDICATED_CHANNEL_QUEUE_NO_SONGS)) else { + var index = 1 + for (track in queueAsList) nextTenSongs.append( + index++ + ).append(". → ").append(track.info.title).append(" - ").append(track.info.author) + .append(" [").append(GeneralUtils.formatTime(track.length)) + .append("]\n") + } } - } - nextTenSongs.append("```") - val msg = msgRequest.await() - msg.editMessage( - localeManager.getMessage( - DedicatedChannelMessages.DEDICATED_CHANNEL_QUEUE_PLAYING, - Pair( - "{songs}", - nextTenSongs.toString() + nextTenSongs.append("```") + msgRequest.queue { msg -> + msg.editMessage( + localeManager.getMessage( + DedicatedChannelMessages.DEDICATED_CHANNEL_QUEUE_PLAYING, + Pair( + "{songs}", + nextTenSongs.toString() + ) + ) ) - ) - ) - .setEmbeds(eb.build()) - .queue() - // TODO: Handle unknown message error properly + .setEmbeds(eb.build()) + .queue() + } + + // TODO: Handle unknown message error properly // msgRequest.queue( // { msg: Message -> // @@ -315,17 +321,18 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S // ) { removeChannel() } // ) + } } } - private suspend fun sendEditErrorMessage(messageChannel: GuildMessageChannel?) { + private fun sendEditErrorMessage(messageChannel: GuildMessageChannel?) { sendErrorMessage( messageChannel, DedicatedChannelMessages.DEDICATED_CHANNEL_SELF_INSUFFICIENT_PERMS_EDIT ) } - private suspend fun sendErrorMessage( + private fun sendErrorMessage( messageChannel: GuildMessageChannel?, message: DedicatedChannelMessages ) { @@ -345,7 +352,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } } - suspend fun updateAll() { + fun updateAll() { if (!isChannelSet()) return @@ -360,7 +367,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S guild.name ) } else { - awaitAll( + CompletableFuture.allOf( buttonUpdate, topicUpdate ) @@ -373,18 +380,16 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } } - suspend fun updateButtons(): Deferred? = coroutineScope { - if (!isChannelSet()) return@coroutineScope null - val job = async { - val msgRequest: RestAction = getMessageRequest() ?: return@async null - val msg = msgRequest.await() - buttonUpdateRequest(msg).await() - } - - return@coroutineScope job + fun updateButtons(): CompletableFuture? { + if (!isChannelSet()) return null + val msgRequest: RestAction = getMessageRequest() ?: return null + return msgRequest.submit() + .thenApply { msg -> + buttonUpdateRequest(msg).submit() + }.join() } - suspend fun buttonUpdateRequest(msg: Message): MessageEditAction { + fun buttonUpdateRequest(msg: Message): MessageEditAction { val localeManager = LocaleManager.getLocaleManager(msg.guild) val validFirstRowItems = RequestChannelButton.firstRow.filter { config.getState(it) } @@ -452,15 +457,13 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S ) } - suspend fun updateTopic(): Deferred? = coroutineScope { - if (!isChannelSet()) return@coroutineScope null - return@coroutineScope async { - val channel: TextChannel? = getTextChannel() - channelTopicUpdateRequest(channel)!!.await() - } + fun updateTopic(): CompletableFuture? { + if (!isChannelSet()) return null + val channel: TextChannel? = getTextChannel() + return channelTopicUpdateRequest(channel)!!.submit() } - suspend fun channelTopicUpdateRequest(channel: TextChannel?): TextChannelManager? { + fun channelTopicUpdateRequest(channel: TextChannel?): TextChannelManager? { if (channel == null) return null val localeManager = LocaleManager.getLocaleManager(channel.guild) return channel.manager.setTopic( @@ -476,13 +479,13 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S ) } - protected suspend fun updateConfig(config: JSONObject) { + protected fun updateConfig(config: JSONObject) { cache.updateGuild(guild.id) { this.dedicated_channel = Json.decodeFromString(config.toString()) } } - suspend fun cleanChannel() { + fun cleanChannel() { if (!isChannelSet()) return if (!guild.selfMember.hasPermission(Permission.MESSAGE_HISTORY)) return val channel = getTextChannel()!! @@ -508,12 +511,12 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S class ChannelConfig internal constructor(private val mainConfig: RequestChannelConfig) { - suspend fun getConfigJsonObject(): JSONObject { + fun getConfigJsonObject(): JSONObject { val guildModel = mainConfig.getGuildModel() return guildModel.dedicated_channel.config?.toJsonObject() ?: RequestChannelConfigModel().toJsonObject() } - suspend fun getState(field: RequestChannelButton): Boolean { + fun getState(field: RequestChannelButton): Boolean { if (!hasField(field)) initConfig() val config: JSONObject = mainConfig .getGuildModel() @@ -523,7 +526,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S return config.getBoolean(field.name.lowercase(Locale.getDefault())) } - suspend fun setState(field: RequestChannelButton, state: Boolean) { + fun setState(field: RequestChannelButton, state: Boolean) { if (!hasField(field)) initConfig() val guildModel = mainConfig.getGuildModel() @@ -537,7 +540,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S mainConfig.updateConfig(fullConfig) } - suspend fun toggleStates(buttons: List) { + fun toggleStates(buttons: List) { val guildModel = mainConfig.getGuildModel() val config = guildModel.dedicated_channel.config!! cache.updateGuild(guildModel.server_id.toString()) { @@ -595,7 +598,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } } - private suspend fun initConfig() { + private fun initConfig() { val config: JSONObject = mainConfig.getGuildModel().toJsonObject() .getJSONObject(GuildDB.Field.REQUEST_CHANNEL_OBJECT.toString()) if (!config.has(GuildDB.Field.REQUEST_CHANNEL_CONFIG.toString())) config.put( @@ -612,7 +615,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S mainConfig.updateConfig(config) } - private suspend fun hasField(field: RequestChannelButton): Boolean { + private fun hasField(field: RequestChannelButton): Boolean { val guildModel = mainConfig.getGuildModel() val config = guildModel.dedicated_channel.config?.toJsonObject() return config?.has(field.name.lowercase(Locale.getDefault())) ?: false @@ -620,7 +623,7 @@ class RequestChannelConfig(private val guild: Guild, private val shardManager: S } - override suspend fun update() { + override fun update() { // Nothing } } \ No newline at end of file diff --git a/src/main/kotlin/main/utils/json/restrictedchannels/RestrictedChannelsConfig.kt b/src/main/kotlin/main/utils/json/restrictedchannels/RestrictedChannelsConfig.kt index 59fa020b..f5464700 100644 --- a/src/main/kotlin/main/utils/json/restrictedchannels/RestrictedChannelsConfig.kt +++ b/src/main/kotlin/main/utils/json/restrictedchannels/RestrictedChannelsConfig.kt @@ -11,7 +11,7 @@ class RestrictedChannelsConfig(private val guild: Guild) : AbstractGuildConfig(g private val logger by SLF4J } - suspend fun addChannel(channelID: Long, type: ChannelType?) { + fun addChannel(channelID: Long, type: ChannelType?) { val configField: GuildDB.Field = when (type) { ChannelType.TEXT_CHANNEL -> GuildDB.Field.RESTRICTED_CHANNELS_TEXT ChannelType.VOICE_CHANNEL -> GuildDB.Field.RESTRICTED_CHANNELS_VOICE @@ -31,7 +31,7 @@ class RestrictedChannelsConfig(private val guild: Guild) : AbstractGuildConfig(g } } - suspend fun removeChannel(channelID: Long, type: ChannelType?) { + fun removeChannel(channelID: Long, type: ChannelType?) { val obj = getGuildModel().toJsonObject() val configField: GuildDB.Field = when (type) { ChannelType.TEXT_CHANNEL -> GuildDB.Field.RESTRICTED_CHANNELS_TEXT @@ -51,7 +51,7 @@ class RestrictedChannelsConfig(private val guild: Guild) : AbstractGuildConfig(g } } - suspend fun getRestrictedChannels(type: ChannelType?): List { + fun getRestrictedChannels(type: ChannelType?): List { val obj = getGuildModel().restricted_channels return when (type) { ChannelType.TEXT_CHANNEL -> obj.text_channels @@ -60,10 +60,10 @@ class RestrictedChannelsConfig(private val guild: Guild) : AbstractGuildConfig(g } } - suspend fun isRestrictedChannel(vcID: Long, type: ChannelType?): Boolean = + fun isRestrictedChannel(vcID: Long, type: ChannelType?): Boolean = getRestrictedChannels(type).contains(vcID) - suspend fun restrictedChannelsToString(type: ChannelType?): String = + fun restrictedChannelsToString(type: ChannelType?): String = getRestrictedChannels(type).joinToString(", ") { channel -> "<#$channel>" } @@ -80,5 +80,5 @@ class RestrictedChannelsConfig(private val guild: Guild) : AbstractGuildConfig(g } - override suspend fun update() {} + override fun update() {} } \ No newline at end of file diff --git a/src/main/kotlin/main/utils/json/themes/ThemesConfig.kt b/src/main/kotlin/main/utils/json/themes/ThemesConfig.kt index 2a5a2547..2baef4cf 100644 --- a/src/main/kotlin/main/utils/json/themes/ThemesConfig.kt +++ b/src/main/kotlin/main/utils/json/themes/ThemesConfig.kt @@ -12,17 +12,17 @@ import java.util.* class ThemesConfig(private val guild: Guild) : AbstractGuildConfig(guild) { - suspend fun getTheme(): RobertifyTheme { + fun getTheme(): RobertifyTheme { return RobertifyTheme.parse(getGuildModel().theme) } - suspend fun setTheme(theme: RobertifyTheme) { + fun setTheme(theme: RobertifyTheme) { cache.updateGuild(guild.id) { this.theme = theme.name.lowercase() } } - override suspend fun update() { + override fun update() { if (!guildHasInfo()) loadGuild() val cacheArr = GuildDBCache.ins.getCache() val obj = cacheArr.getJSONObject(getIndexOfObjectInArray(cacheArr, GuildDB.Field.GUILD_ID, guild.idLong)) diff --git a/src/main/kotlin/main/utils/json/toggles/TogglesConfig.kt b/src/main/kotlin/main/utils/json/toggles/TogglesConfig.kt index ff2f61a1..6d2b902a 100644 --- a/src/main/kotlin/main/utils/json/toggles/TogglesConfig.kt +++ b/src/main/kotlin/main/utils/json/toggles/TogglesConfig.kt @@ -80,7 +80,7 @@ class TogglesConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun get(toggle: Toggle): Boolean { + fun get(toggle: Toggle): Boolean { if (!guildHasInfo()) loadGuild() val toggles = getTogglesJson(); @@ -102,17 +102,17 @@ class TogglesConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } } - suspend fun getToggle(toggle: Toggle): Boolean = get(toggle) + fun getToggle(toggle: Toggle): Boolean = get(toggle) - suspend fun getDJToggles(): DJTogglesModel { + fun getDJToggles(): DJTogglesModel { return getToggles().dj_toggles } - suspend fun getLogToggles(): LogTogglesModel { + fun getLogToggles(): LogTogglesModel { return getToggles().log_toggles } - suspend fun getDJToggle(cmd: AbstractSlashCommand): Boolean { + fun getDJToggle(cmd: AbstractSlashCommand): Boolean { if (!SlashCommandManager.isMusicCommand(cmd)) return false @@ -124,7 +124,7 @@ class TogglesConfig(private val guild: Guild) : AbstractGuildConfig(guild) { } else djToggles.getBoolean(cmd.info.name.lowercase()) } - suspend fun setToggle(toggle: Toggle, value: Boolean) { + fun setToggle(toggle: Toggle, value: Boolean) { val guildModel = getGuildModel().toJsonObject(); guildModel.getJSONObject(GuildDB.Field.TOGGLES_OBJECT.toString()) .put(toggle.toString(), value) @@ -132,7 +132,7 @@ class TogglesConfig(private val guild: Guild) : AbstractGuildConfig(guild) { cache.updateGuild(newModel) } - suspend fun setDJToggle(command: AbstractSlashCommand, value: Boolean) { + fun setDJToggle(command: AbstractSlashCommand, value: Boolean) { val guildModel = getGuildModel().toJsonObject(); guildModel.getJSONObject(GuildDB.Field.TOGGLES_OBJECT.toString()) .getJSONObject(GuildDB.Field.TOGGLES_DJ.toString()) @@ -141,7 +141,7 @@ class TogglesConfig(private val guild: Guild) : AbstractGuildConfig(guild) { cache.updateGuild(newModel) } - suspend fun setDJToggle(commands: List, value: Boolean) { + fun setDJToggle(commands: List, value: Boolean) { val guildModel = getGuildModel().toJsonObject(); val djObj = guildModel.getJSONObject(GuildDB.Field.TOGGLES_OBJECT.toString()) .getJSONObject(GuildDB.Field.TOGGLES_DJ.toString()) @@ -150,7 +150,7 @@ class TogglesConfig(private val guild: Guild) : AbstractGuildConfig(guild) { cache.updateGuild(newModel) } - suspend fun setLogToggle(type: LogType, state: Boolean) { + fun setLogToggle(type: LogType, state: Boolean) { if (!isLogToggleSet(type)) update() val obj = getGuildModel().toJsonObject() obj.getJSONObject(GuildDB.Field.TOGGLES_OBJECT.toString()) @@ -160,7 +160,7 @@ class TogglesConfig(private val guild: Guild) : AbstractGuildConfig(guild) { cache.updateGuild(newModel) } - suspend fun getLogToggle(type: LogType): Boolean { + fun getLogToggle(type: LogType): Boolean { if (!isLogToggleSet(type)) update() val obj = getGuildModel().toJsonObject() return obj.getJSONObject(GuildDB.Field.TOGGLES_OBJECT.toString()) @@ -168,29 +168,29 @@ class TogglesConfig(private val guild: Guild) : AbstractGuildConfig(guild) { .getBoolean(type.name.lowercase(Locale.getDefault())) } - suspend fun isDJToggleSet(cmd: AbstractSlashCommand): Boolean = + fun isDJToggleSet(cmd: AbstractSlashCommand): Boolean = getDJToggles().toJsonObject().has(cmd.info.name.lowercase()) - suspend fun isDJToggleSet(cmd: String): Boolean = + fun isDJToggleSet(cmd: String): Boolean = getDJToggles().toJsonObject().has(cmd.lowercase(Locale.getDefault())) - suspend fun isLogToggleSet(type: LogType): Boolean = try { + fun isLogToggleSet(type: LogType): Boolean = try { getLogToggles().toJsonObject().has(type.name.lowercase(Locale.getDefault())) } catch (e: JSONException) { false } - suspend fun getToggles(): TogglesModel { + fun getToggles(): TogglesModel { return getGuildModel().toggles ?: run { update() return@run getGuildModel().toggles!! } } - suspend fun getTogglesJson(): JSONObject = getToggles().toJsonObject() + fun getTogglesJson(): JSONObject = getToggles().toJsonObject() - override suspend fun update() { + override fun update() { if (!guildHasInfo()) loadGuild() val cacheArr = GuildDBCache.ins.getCache() val `object` = cacheArr.getJSONObject(getIndexOfObjectInArray(cacheArr, GuildDB.Field.GUILD_ID, guild.idLong)) diff --git a/src/main/kotlin/main/utils/locale/LocaleManager.kt b/src/main/kotlin/main/utils/locale/LocaleManager.kt index 28b98079..18033433 100644 --- a/src/main/kotlin/main/utils/locale/LocaleManager.kt +++ b/src/main/kotlin/main/utils/locale/LocaleManager.kt @@ -1,5 +1,6 @@ package main.utils.locale +import kotlinx.coroutines.runBlocking import main.utils.GeneralUtils import main.utils.GeneralUtils.setContent import main.utils.json.locale.LocaleConfig @@ -77,26 +78,26 @@ class LocaleManager private constructor(private val guild: Guild?, _locale: Robe } - suspend fun getLocale(): RobertifyLocale { + fun getLocale(): RobertifyLocale { if (guild == null) return RobertifyLocale.ENGLISH return LocaleConfig(guild).getLocale() } - suspend fun setLocale(locale: RobertifyLocale) { + fun setLocale(locale: RobertifyLocale) { locales.putIfAbsent(locale, retrieveLocaleFile(locale)) if (guild != null) LocaleConfig(guild).setLocale(locale) } - suspend fun getLocaleFile(): Map { + fun getLocaleFile(): Map { return locales.computeIfAbsent(getLocale()) { retrieveLocaleFile(it) } } - suspend fun getMessage(message: LocaleMessage, vararg placeholders: Pair): String { + fun getMessage(message: LocaleMessage, vararg placeholders: Pair): String { var msg = getLocaleFile()[message.name.lowercase()] ?: throw NullPointerException("There was no such message found in the mapping with key: ${message.name}") diff --git a/src/main/kotlin/main/utils/managers/RandomMessageManager.kt b/src/main/kotlin/main/utils/managers/RandomMessageManager.kt index 7bdc69a6..dd3c2775 100644 --- a/src/main/kotlin/main/utils/managers/RandomMessageManager.kt +++ b/src/main/kotlin/main/utils/managers/RandomMessageManager.kt @@ -26,14 +26,14 @@ class RandomMessageManager { val hasMessages: Boolean get() = messages.isEmpty() - suspend fun getMessage(guild: Guild): MessageEmbed { + fun getMessage(guild: Guild): MessageEmbed { val localeManager = LocaleManager[guild] val messages = BotDBCache.instance.getRandomMessages() if (messages.isEmpty()) throw NullPointerException(localeManager.getMessage(RandomMessages.NO_RANDOM_MESSAGES)) - return RobertifyEmbedUtils.embedMessage(guild, messages.get(Random.nextInt(messages.size))) + return RobertifyEmbedUtils.embedMessage(guild, messages[Random.nextInt(messages.size)]) .setTitle(localeManager.getMessage(RandomMessages.TIP_TITLE)) .setFooter(localeManager.getMessage(RandomMessages.TIP_FOOTER)) .setTimestamp(Instant.now()) @@ -52,7 +52,7 @@ class RandomMessageManager { fun clearMessages() = unaryMinus() - suspend fun randomlySendMessage(channel: GuildMessageChannel) { + fun randomlySendMessage(channel: GuildMessageChannel) { val guild = channel.guild if (!TogglesConfig(guild).getToggle(Toggle.TIPS)) return diff --git a/src/main/kotlin/main/utils/pagination/PaginationHandler.kt b/src/main/kotlin/main/utils/pagination/PaginationHandler.kt index 4a562aa1..abbcf007 100644 --- a/src/main/kotlin/main/utils/pagination/PaginationHandler.kt +++ b/src/main/kotlin/main/utils/pagination/PaginationHandler.kt @@ -345,8 +345,8 @@ object PaginationHandler { items.add( QueueItem( trackIndex = i + 1, - trackTitle = track.title.coerceAtMost(30), - artist = track.author.coerceAtMost(30), + trackTitle = track.info.title.coerceAtMost(30), + artist = track.info.author.coerceAtMost(30), duration = track.length ) ) @@ -366,8 +366,8 @@ object PaginationHandler { page.addItem( QueueItem( trackIndex = lastIndex + 1, - trackTitle = track.title, - artist = track.author, + trackTitle = track.info.title, + artist = track.info.author, duration = track.length ) ) diff --git a/src/main/kotlin/main/utils/resume/GuildResumeManager.kt b/src/main/kotlin/main/utils/resume/GuildResumeManager.kt index 91459081..75a7da9f 100644 --- a/src/main/kotlin/main/utils/resume/GuildResumeManager.kt +++ b/src/main/kotlin/main/utils/resume/GuildResumeManager.kt @@ -24,7 +24,7 @@ // // val channel = selfVoiceState.channel!!.id // val allTracks = mutableListOf() -// val playingTrack = scheduler.player.playingTrack +// val playingTrack = scheduler.player.track // // if (playingTrack != null) { // val requester = scheduler.findRequester(playingTrack.identifier)