All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.arbjerg.lavalink.internal.LavalinkRestClient.kt Maven / Gradle / Ivy

package dev.arbjerg.lavalink.internal

import dev.arbjerg.lavalink.client.LavalinkNode
import dev.arbjerg.lavalink.client.http.HttpBuilder
import dev.arbjerg.lavalink.internal.error.RestException
import dev.arbjerg.lavalink.protocol.v4.*
import kotlinx.serialization.encodeToString
import okhttp3.Call
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import reactor.core.publisher.Mono
import java.io.IOException
import java.net.URLEncoder
import java.nio.charset.StandardCharsets

class LavalinkRestClient(val node: LavalinkNode) {
    fun getPlayers(): Mono {
        return newRequest {
            path("/v4/sessions/${node.sessionId}/players")
        }.toMono()
    }

    fun getPlayer(guildId: Long): Mono {
        return newRequest {
            path("/v4/sessions/${node.sessionId}/players/$guildId")
        }.toMono()
    }

    fun updatePlayer(player: PlayerUpdate, guildId: Long, noReplace: Boolean = false): Mono {
        return newRequest {
            path("/v4/sessions/${node.sessionId}/players/$guildId?noReplace=$noReplace")
            patch(json.encodeToString(player).toRequestBody("application/json".toMediaType()))
        }.toMono()
    }

    fun destroyPlayer(guildId: Long): Mono {
        return newRequest {
            path("/v4/sessions/${node.sessionId}/players/$guildId")
            delete()
        }.toMono()
    }

    fun loadItem(identifier: String): Mono {
        val encId = URLEncoder.encode(identifier, StandardCharsets.UTF_8)

        return newRequest {
            path("/v4/loadtracks?identifier=$encId")
        }.toMono()
    }

    fun decodeTrack(encoded: String): Mono {
        return newRequest {
            path("/v4/decodetrack?encodedTrack=$encoded")
        }.toMono()
    }

    fun decodeTracks(encoded: List): Mono {
        return newRequest {
            path("/v4/decodetracks")
            post(json.encodeToString(encoded).toRequestBody("application/json".toMediaType()))
        }.toMono()
    }

    fun getNodeInfo(): Mono {
        return newRequest {
            path("/v4/info")
        }.toMono()
    }

    /**
     * Make a request to the lavalink node. This is internal to keep it looking nice in kotlin. Java compatibility is in the node class.
     */
    internal fun newRequest(configure: HttpBuilder.() -> HttpBuilder): Call {
        val requestBuilder = Request.Builder()
            .addHeader("Authorization", node.password)
            .get()
        val builder = configure(HttpBuilder(requestBuilder))

        return node.httpClient.newCall(builder.finalizeUrl(node.baseUri).build())
    }

    private inline fun  Call.toMono(): Mono {
        return Mono.create { sink ->
            sink.onCancel {
                // try to cancel the request
                this.cancel()
            }
            this.enqueue(object : okhttp3.Callback {
                override fun onFailure(call: Call, e: IOException) {
                    sink.error(e)
                }

                override fun onResponse(call: Call, response: Response) {
                    response.use { res ->
                        res.body?.use { body ->
                            if (res.code > 299) {
                                val error = json.decodeFromString(body.string())

                                sink.error(RestException(error))
                                return
                            }

                            if (res.code == 204) {
                                sink.success()
                                return
                            }

                            val parsed = json.decodeFromString(body.string())

                            sink.success(parsed)
                        }
                    }
                }
            })
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy