Skip to content

Commit

Permalink
Update Java Example
Browse files Browse the repository at this point in the history
  • Loading branch information
DRSchlaubi committed Jul 27, 2023
1 parent 0dc1b1f commit 08c50a1
Show file tree
Hide file tree
Showing 20 changed files with 187 additions and 770 deletions.
6 changes: 0 additions & 6 deletions .idea/kotlinScripting.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package dev.schlaubi.lavakord
/**
* Marks a declaration as part of the low-level REST api mapping.
*/
@RequiresOptIn("This API is an unsafe low-level mapping of the Lavalink REST API! Use with care.")
@RequiresOptIn(
"This API is an unsafe low-level mapping of the Lavalink REST API! Use with care.",
RequiresOptIn.Level.WARNING
)
@MustBeDocumented
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,23 @@ import dev.arbjerg.lavalink.protocol.v4.Error
import dev.schlaubi.lavakord.audio.Link
import io.ktor.client.request.*


/**
* Exception thrown when there is no permission to perform a certain action.
*
* @property permission the required but missing permission
*/
public class InsufficientPermissionException(@Suppress("MemberVisibilityCanBePrivate") public val permission: String) :
RuntimeException("Action cannot be performed due to lack of $permission")
IllegalStateException("Action cannot be performed due to lack of $permission")

/**
* Exception thrown on [Link.addressStatus] when there is no route planner set in Lavalink configuration.
*/
public class NoRoutePlannerException : RuntimeException("No route planner was set")
public class NoRoutePlannerException : IllegalStateException("No route planner was set")

/**
* Exception indicating a REST request failed.
*
* @property error the [RestError] response
* @property request the [HttpRequest] which failed
*/
public data class RestException(val error: Error, val request: HttpRequest) : RuntimeException(error.message)
public data class RestException(val error: Error, val request: HttpRequest) : IllegalStateException(error.message)
20 changes: 0 additions & 20 deletions core/src/commonMain/kotlin/dev/schlaubi/lavakord/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,3 @@ internal fun Player.checkImplementation() {
}
require(this is WebsocketPlayer) { "This has to be a internal implementation instance" }
}

/**
* Port of Java [Map.computeIfAbsent](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-) to Kotlin MPP.
*/
public fun <K, V> MutableMap<K, V>.computeIfAbsent(
key: K,
mappingFunction: (K) -> V
): V {
val v = get(key)
if (v == null) {
val newValue = mappingFunction(key)
if (newValue != null) {
put(key, newValue)
return newValue
}
}

return v!!
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import dev.schlaubi.lavakord.RestException
import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.audio.Node
import dev.schlaubi.lavakord.audio.RestNode
import dev.schlaubi.lavakord.computeIfAbsent
import dev.schlaubi.lavakord.internal.HttpEngine
import dev.schlaubi.lavakord.internal.RestNodeImpl
import dev.schlaubi.lavakord.rest.updatePlayer
Expand All @@ -27,12 +26,7 @@ import kotlinx.coroutines.launch
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual
import kotlinx.serialization.modules.plus
import kotlin.collections.List
import kotlin.collections.Map
import kotlin.collections.MutableMap
import kotlin.collections.mutableMapOf
import kotlin.collections.set
import kotlin.collections.toList

/**
* Abstract implementation of [LavaKord].
Expand Down Expand Up @@ -135,7 +129,7 @@ public abstract class AbstractLavakord internal constructor(
internal fun removeDestroyedLink(link: Link) = linksMap.remove(link.guildId)

override fun getLink(guildId: ULong): Link {
return linksMap.computeIfAbsent(guildId) {
return linksMap.getOrPut(guildId) {
val node = loadBalancer.determineBestNode(guildId) as NodeImpl
buildNewLink(guildId, node)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ internal class NodeImpl(
}

retry.reset()
available = true

LOG.debug { "Successfully connected to node: $name ($host)" }

Expand Down Expand Up @@ -185,6 +184,7 @@ internal class NodeImpl(
}

is Message.ReadyEvent -> {
available = true
sessionId = event.sessionId
updateSession(
SessionUpdate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ import io.ktor.client.request.*
* Updates the current session.
*/
@UnsafeRestApi
public suspend fun RestNode.updateSession(sessionId: String, request: SessionUpdate): Session = patch(
V4Api.Sessions.Specific(sessionId)
) {
setBody(request)
}
public suspend fun RestNode.updateSession(sessionId: String, request: SessionUpdate): Session =
patch(V4Api.Sessions.Specific(sessionId)) {
setBody(request)
}

/**
* Updates the current session.
Expand Down
6 changes: 6 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# example

This is an example for Lavalink.kt

- [Kotlin (JS/JVM using Kord)](src/commonMain/kotlin/Lavakord.kt)
- [Java using JDA](src/jvmMain/java/dev/schlaubi/lavakord/Javakord.java)
58 changes: 42 additions & 16 deletions example/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
plugins {
java
kotlin("jvm")
kotlin("kapt")
kotlin("multiplatform")
}

group = "me.schlaubi.lavakord"
Expand All @@ -14,23 +13,50 @@ repositories {
mavenCentral()
}

dependencies {
implementation(projects.kord)
implementation(projects.jdaJava)
implementation(projects.plugins.lavasrc)
implementation(projects.plugins.sponsorblock)
implementation(libs.sl4fj.simple)
implementation(libs.kord.core)
kotlin {
jvmToolchain(19)
jvm {
withJava()
}
js(IR) {
nodejs()
}

sourceSets {
commonMain {
dependencies {
implementation(libs.kord.core)
implementation(projects.kord)
implementation(projects.plugins.lavasrc)
implementation(projects.plugins.sponsorblock)
}
}

implementation("org.apache.groovy:groovy-all:4.0.7")
implementation("org.jetbrains.kotlinx:atomicfu:0.20.2")
kapt("dev.kord.x:commands-processor:0.4.0-SNAPSHOT")
named("jvmMain") {
dependencies {
implementation(projects.jdaJava)
implementation(libs.sl4fj.simple)
implementation(libs.kord.core)

implementation("net.dv8tion:JDA:5.0.0-alpha.3") {
exclude(module = "opus-java")
implementation("org.apache.groovy:groovy-all:4.0.7")
implementation("org.jetbrains.kotlinx:atomicfu:0.20.2")

implementation("net.dv8tion:JDA:v5.0.0-beta.12") {
exclude(module = "opus-java")
}
}
}

named("jsMain") {
dependencies {
implementation(libs.kotlinx.nodejs)
}
}
}
}

kotlin {
jvmToolchain(19)
tasks {
withType<JavaCompile> {
options.compilerArgs.add("--enable-preview")
}
}
111 changes: 111 additions & 0 deletions example/src/commonMain/kotlin/Lavakord.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
@file:Suppress("unused", "KDocMissingDocumentation")

package dev.schlaubi.lavakord

import dev.arbjerg.lavalink.protocol.v4.LoadResult
import dev.kord.common.entity.Snowflake
import dev.kord.core.Kord
import dev.kord.core.behavior.interaction.response.FollowupPermittingInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.createEphemeralFollowup
import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.event.interaction.GuildChatInputCommandInteractionCreateEvent
import dev.kord.core.on
import dev.kord.gateway.Intent
import dev.kord.gateway.PrivilegedIntent
import dev.kord.rest.builder.interaction.string
import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.audio.on
import dev.schlaubi.lavakord.kord.getLink
import dev.schlaubi.lavakord.kord.lavakord
import dev.schlaubi.lavakord.plugins.lavasrc.LavaSrc
import dev.schlaubi.lavakord.plugins.sponsorblock.Sponsorblock
import dev.schlaubi.lavakord.plugins.sponsorblock.model.Category
import dev.schlaubi.lavakord.plugins.sponsorblock.rest.putSponsorblockCategories
import dev.schlaubi.lavakord.rest.loadItem

lateinit var lavalink: LavaKord

expect fun getEnv(name: String): String?

@OptIn(PrivilegedIntent::class)
suspend fun main() {
val kord = Kord(getEnv("token") ?: error("Missing token"))
kord.createGlobalApplicationCommands {
input("connect", "Connects to your channel")
input("pause", "Pauses the player")
input("stop", "Stops the player")
input("leave", "Leaves the channel")
input("play", "Starts playing a track") {
string("query", "The query you want to play")
}
}

val listenedGuilds = mutableListOf<Snowflake>()
lavalink = kord.lavakord {
plugins {
install(LavaSrc)
install(Sponsorblock)
}
}

lavalink.addNode("ws://localhost:2333", "youshallnotpass")

kord.on<GuildChatInputCommandInteractionCreateEvent> {
val ack = interaction.deferPublicResponse()
val link = lavalink.getLink(interaction.guildId)
val player = link.player
player.putSponsorblockCategories(Category.MusicOfftopic)
if (interaction.guildId !in listenedGuilds) {
val followUpCreator = FollowupPermittingInteractionResponseBehavior(
interaction.applicationId, interaction.token, interaction.kord, interaction.supplier
)
player.on {
followUpCreator.createEphemeralFollowup { content = "Event: $this" }
}
listenedGuilds.add(interaction.guildId)
}

when (interaction.command.rootName) {
"connect" -> {
val voiceState = this.interaction.user.asMember(interaction.guildId).getVoiceState()

val channelId = voiceState.channelId
if (channelId == null) {
ack.respond { content = "Please connectAudio to a voice channel" }
return@on
}

link.connectAudio(channelId.value)
}

"pause" -> player.pause(!player.paused)
"stop" -> player.stopTrack()
"leave" -> link.destroy()
"play" -> {
val query = interaction.command.options["query"]?.value.toString()
val search = if (query.startsWith("http")) {
query
} else {
"ytsearch:$query"
}

if (link.state != Link.State.CONNECTED) {
ack.respond { content = "Not connectAudio to VC!" }
return@on
}

when (val item = link.loadItem(search)) {
is LoadResult.TrackLoaded -> player.playTrack(track = item.data)
is LoadResult.PlaylistLoaded -> player.playTrack(track = item.data.tracks.first())
is LoadResult.SearchResult -> player.playTrack(item.data.tracks.first())
is LoadResult.NoMatches -> ack.respond { content = "No matches" }
is LoadResult.LoadFailed -> ack.respond { content = item.data.message ?: "Exception" }
}
}
}
}

kord.login {
intents += Intent.MessageContent
}
}
5 changes: 5 additions & 0 deletions example/src/jsMain/kotlin/dev/schlaubi/lavakord/Platform.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dev.schlaubi.lavakord

import node.process.process

actual fun getEnv(name: String) = process.env[name]
File renamed without changes.
3 changes: 3 additions & 0 deletions example/src/jvmMain/kotlin/dev/schlaubi/lavakord/Platform.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dev.schlaubi.lavakord

actual fun getEnv(name: String): String? = System.getenv(name)
Loading

0 comments on commit 08c50a1

Please sign in to comment.