diff --git a/build.gradle.kts b/build.gradle.kts
index d5e9d2a5..054dbfbf 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,7 +11,7 @@ plugins {
}
group = "me.schlaubi"
-version = "0.1"
+version = "0.2"
repositories {
mavenCentral()
diff --git a/docs/lavakord/index.html b/docs/lavakord/index.html
index 7dca8e79..84cbdd5b 100644
--- a/docs/lavakord/index.html
+++ b/docs/lavakord/index.html
@@ -35,6 +35,17 @@
Packages
+
+
+
+
diff --git a/docs/lavakord/package-list b/docs/lavakord/package-list
index 0e89a709..dcbf8e0f 100644
--- a/docs/lavakord/package-list
+++ b/docs/lavakord/package-list
@@ -2,4 +2,5 @@ $dokka.format:html-v1
$dokka.linkExtension:html
me.schlaubi.lavakord
+me.schlaubi.lavakord.rest
diff --git a/docs/navigation.html b/docs/navigation.html
index 8cc23235..480e5fa2 100644
--- a/docs/navigation.html
+++ b/docs/navigation.html
@@ -21,5 +21,17 @@
+
diff --git a/docs/scripts/navigation-pane.json b/docs/scripts/navigation-pane.json
index 365658d4..af087e89 100644
--- a/docs/scripts/navigation-pane.json
+++ b/docs/scripts/navigation-pane.json
@@ -1 +1 @@
-[{"name":"lavakord","label":"lavakord","searchKey":"lavakord","dri":"////PointingToDeclaration/","location":"lavakord/index.html"},{"name":"me.schlaubi.lavakord","label":"me.schlaubi.lavakord","searchKey":"me.schlaubi.lavakord","dri":"me.schlaubi.lavakord////PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/index.html"},{"name":"connect","label":"connect","searchKey":"connect","dri":"me.schlaubi.lavakord//connect/lavalink.client.io.Link#com.gitlab.kordlib.core.entity.channel.VoiceChannel/PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/connect.html"},{"name":"getLink","label":"getLink","searchKey":"getLink","dri":"me.schlaubi.lavakord//getLink/lavalink.client.io.Lavalink[TypeParam(bounds=[lavalink.client.io.Link])]#com.gitlab.kordlib.common.entity.Snowflake/PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/get-link.html"},{"name":"InsufficientPermissionException","label":"InsufficientPermissionException","searchKey":"InsufficientPermissionException","dri":"me.schlaubi.lavakord/InsufficientPermissionException///PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/-insufficient-permission-exception/index.html"},{"name":"KordLinkOptions","label":"KordLinkOptions","searchKey":"KordLinkOptions","dri":"me.schlaubi.lavakord/KordLinkOptions///PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/-kord-link-options/index.html"},{"name":"lavalink","label":"lavalink","searchKey":"lavalink","dri":"me.schlaubi.lavakord//lavalink/com.gitlab.kordlib.core.Kord#kotlin.Function1[me.schlaubi.lavakord.MutableKordLinkOptions,kotlin.Unit]/PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/lavalink.html"},{"name":"MutableKordLinkOptions","label":"MutableKordLinkOptions","searchKey":"MutableKordLinkOptions","dri":"me.schlaubi.lavakord/MutableKordLinkOptions///PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/-mutable-kord-link-options/index.html"}]
+[{"name":"lavakord","label":"lavakord","searchKey":"lavakord","dri":"////PointingToDeclaration/","location":"lavakord/index.html"},{"name":"me.schlaubi.lavakord","label":"me.schlaubi.lavakord","searchKey":"me.schlaubi.lavakord","dri":"me.schlaubi.lavakord////PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/index.html"},{"name":"connect","label":"connect","searchKey":"connect","dri":"me.schlaubi.lavakord//connect/lavalink.client.io.Link#com.gitlab.kordlib.core.entity.channel.VoiceChannel/PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/connect.html"},{"name":"getLink","label":"getLink","searchKey":"getLink","dri":"me.schlaubi.lavakord//getLink/lavalink.client.io.Lavalink[TypeParam(bounds=[lavalink.client.io.Link])]#com.gitlab.kordlib.common.entity.Snowflake/PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/get-link.html"},{"name":"InsufficientPermissionException","label":"InsufficientPermissionException","searchKey":"InsufficientPermissionException","dri":"me.schlaubi.lavakord/InsufficientPermissionException///PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/-insufficient-permission-exception/index.html"},{"name":"KordLinkOptions","label":"KordLinkOptions","searchKey":"KordLinkOptions","dri":"me.schlaubi.lavakord/KordLinkOptions///PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/-kord-link-options/index.html"},{"name":"lavalink","label":"lavalink","searchKey":"lavalink","dri":"me.schlaubi.lavakord//lavalink/com.gitlab.kordlib.core.Kord#kotlin.Function1[me.schlaubi.lavakord.MutableKordLinkOptions,kotlin.Unit]/PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/lavalink.html"},{"name":"MutableKordLinkOptions","label":"MutableKordLinkOptions","searchKey":"MutableKordLinkOptions","dri":"me.schlaubi.lavakord/MutableKordLinkOptions///PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord/-mutable-kord-link-options/index.html"},{"name":"me.schlaubi.lavakord.rest","label":"me.schlaubi.lavakord.rest","searchKey":"me.schlaubi.lavakord.rest","dri":"me.schlaubi.lavakord.rest////PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord.rest/index.html"},{"name":"loadItem","label":"loadItem","searchKey":"loadItem","dri":"me.schlaubi.lavakord.rest//loadItem/lavalink.client.io.Link#kotlin.String#com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler/PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord.rest/load-item.html"},{"name":"mapToAudioTrack","label":"mapToAudioTrack","searchKey":"mapToAudioTrack","dri":"me.schlaubi.lavakord.rest//mapToAudioTrack/kotlin.collections.List[me.schlaubi.lavakord.rest.TrackResponse.Track]#/PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord.rest/map-to-audio-track.html"},{"name":"TrackResponse","label":"TrackResponse","searchKey":"TrackResponse","dri":"me.schlaubi.lavakord.rest/TrackResponse///PointingToDeclaration/","location":"lavakord/me.schlaubi.lavakord.rest/-track-response/index.html"}]
diff --git a/docs/scripts/pages.js b/docs/scripts/pages.js
index 4c992271..220f47c8 100644
--- a/docs/scripts/pages.js
+++ b/docs/scripts/pages.js
@@ -4,5 +4,54 @@ var pages = [{'name': 'class InsufficientPermissionException(permission: Permiss
{'name': 'data class MutableKordLinkOptions(autoReconnect: Boolean) : KordLinkOptions', 'description':'me.schlaubi.lavakord.MutableKordLinkOptions', 'location':'lavakord/me.schlaubi.lavakord/-mutable-kord-link-options/index.html', 'searchKey':'MutableKordLinkOptions'},
{'name': 'fun MutableKordLinkOptions(autoReconnect: Boolean)', 'description':'me.schlaubi.lavakord.MutableKordLinkOptions.MutableKordLinkOptions', 'location':'lavakord/me.schlaubi.lavakord/-mutable-kord-link-options/-mutable-kord-link-options.html', 'searchKey':'MutableKordLinkOptions'},
{'name': 'operator fun component1(): Boolean', 'description':'me.schlaubi.lavakord.MutableKordLinkOptions.component1', 'location':'lavakord/me.schlaubi.lavakord/-mutable-kord-link-options/component1.html', 'searchKey':'component1'},
+{'name': 'operator fun component1(): String', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Error.component1', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-error/component1.html', 'searchKey':'component1'},
+{'name': 'operator fun component1(): String?', 'description':'me.schlaubi.lavakord.rest.TrackResponse.NullablePlaylistInfo.component1', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-nullable-playlist-info/component1.html', 'searchKey':'component1'},
+{'name': 'operator fun component1(): String', 'description':'me.schlaubi.lavakord.rest.TrackResponse.PlaylistInfo.component1', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-playlist-info/component1.html', 'searchKey':'component1'},
+{'name': 'operator fun component1(): String', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.component1', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/component1.html', 'searchKey':'component1'},
+{'name': 'operator fun component1(): String', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.component1', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/component1.html', 'searchKey':'component1'},
+{'name': 'operator fun component1(): TrackResponse.LoadType', 'description':'me.schlaubi.lavakord.rest.TrackResponse.component1', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/component1.html', 'searchKey':'component1'},
{'name': 'fun copy(autoReconnect: Boolean): MutableKordLinkOptions', 'description':'me.schlaubi.lavakord.MutableKordLinkOptions.copy', 'location':'lavakord/me.schlaubi.lavakord/-mutable-kord-link-options/copy.html', 'searchKey':'copy'},
-{'name': 'fun Kord.lavalink(configure: MutableKordLinkOptions.() -> Unit): Lavalink', 'description':'me.schlaubi.lavakord.lavalink', 'location':'lavakord/me.schlaubi.lavakord/lavalink.html', 'searchKey':'lavalink'}]
+{'name': 'fun copy(message: String, severity: FriendlyException.Severity): TrackResponse.Error', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Error.copy', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-error/copy.html', 'searchKey':'copy'},
+{'name': 'fun copy(name: String?, selectedTrack: Int?): TrackResponse.NullablePlaylistInfo', 'description':'me.schlaubi.lavakord.rest.TrackResponse.NullablePlaylistInfo.copy', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-nullable-playlist-info/copy.html', 'searchKey':'copy'},
+{'name': 'fun copy(name: String, selectedTrack: Int): TrackResponse.PlaylistInfo', 'description':'me.schlaubi.lavakord.rest.TrackResponse.PlaylistInfo.copy', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-playlist-info/copy.html', 'searchKey':'copy'},
+{'name': 'fun copy(identifier: String, isSeekable: Boolean, author: String, length: Long, isStream: Boolean, position: Int, title: String, uri: String): TrackResponse.Track.Info', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.copy', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/copy.html', 'searchKey':'copy'},
+{'name': 'fun copy(track: String, info: TrackResponse.Track.Info): TrackResponse.Track', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.copy', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/copy.html', 'searchKey':'copy'},
+{'name': 'fun copy(loadType: TrackResponse.LoadType, playlistInfo: TrackResponse.NullablePlaylistInfo, tracks: List, exception: TrackResponse.Error?): TrackResponse', 'description':'me.schlaubi.lavakord.rest.TrackResponse.copy', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/copy.html', 'searchKey':'copy'},
+{'name': 'fun Kord.lavalink(configure: MutableKordLinkOptions.() -> Unit): Lavalink', 'description':'me.schlaubi.lavakord.lavalink', 'location':'lavakord/me.schlaubi.lavakord/lavalink.html', 'searchKey':'lavalink'},
+{'name': 'data class TrackResponse(loadType: TrackResponse.LoadType, playlistInfo: TrackResponse.NullablePlaylistInfo, tracks: List, exception: TrackResponse.Error?)', 'description':'me.schlaubi.lavakord.rest.TrackResponse', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/index.html', 'searchKey':'TrackResponse'},
+{'name': 'fun TrackResponse(loadType: TrackResponse.LoadType, playlistInfo: TrackResponse.NullablePlaylistInfo, tracks: List, exception: TrackResponse.Error?)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.TrackResponse', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track-response.html', 'searchKey':'TrackResponse'},
+{'name': 'data class Error(message: String, severity: FriendlyException.Severity)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Error', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-error/index.html', 'searchKey':'Error'},
+{'name': 'fun Error(message: String, severity: FriendlyException.Severity)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Error.Error', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-error/-error.html', 'searchKey':'Error'},
+{'name': 'operator fun component2(): FriendlyException.Severity', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Error.component2', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-error/component2.html', 'searchKey':'component2'},
+{'name': 'operator fun component2(): Int?', 'description':'me.schlaubi.lavakord.rest.TrackResponse.NullablePlaylistInfo.component2', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-nullable-playlist-info/component2.html', 'searchKey':'component2'},
+{'name': 'operator fun component2(): Int', 'description':'me.schlaubi.lavakord.rest.TrackResponse.PlaylistInfo.component2', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-playlist-info/component2.html', 'searchKey':'component2'},
+{'name': 'operator fun component2(): Boolean', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.component2', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/component2.html', 'searchKey':'component2'},
+{'name': 'operator fun component2(): TrackResponse.Track.Info', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.component2', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/component2.html', 'searchKey':'component2'},
+{'name': 'operator fun component2(): TrackResponse.NullablePlaylistInfo', 'description':'me.schlaubi.lavakord.rest.TrackResponse.component2', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/component2.html', 'searchKey':'component2'},
+{'name': 'fun toFriendlyException(): FriendlyException', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Error.toFriendlyException', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-error/to-friendly-exception.html', 'searchKey':'toFriendlyException'},
+{'name': 'enum LoadType : Enum ', 'description':'me.schlaubi.lavakord.rest.TrackResponse.LoadType', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-load-type/index.html', 'searchKey':'LoadType'},
+{'name': 'LOAD_FAILED()', 'description':'me.schlaubi.lavakord.rest.TrackResponse.LoadType.LOAD_FAILED', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-load-type/-l-o-a-d_-f-a-i-l-e-d/index.html', 'searchKey':'LOAD_FAILED'},
+{'name': 'NO_MATCHES()', 'description':'me.schlaubi.lavakord.rest.TrackResponse.LoadType.NO_MATCHES', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-load-type/-n-o_-m-a-t-c-h-e-s/index.html', 'searchKey':'NO_MATCHES'},
+{'name': 'PLAYLIST_LOADED()', 'description':'me.schlaubi.lavakord.rest.TrackResponse.LoadType.PLAYLIST_LOADED', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-load-type/-p-l-a-y-l-i-s-t_-l-o-a-d-e-d/index.html', 'searchKey':'PLAYLIST_LOADED'},
+{'name': 'SEARCH_RESULT()', 'description':'me.schlaubi.lavakord.rest.TrackResponse.LoadType.SEARCH_RESULT', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-load-type/-s-e-a-r-c-h_-r-e-s-u-l-t/index.html', 'searchKey':'SEARCH_RESULT'},
+{'name': 'TRACK_LOADED()', 'description':'me.schlaubi.lavakord.rest.TrackResponse.LoadType.TRACK_LOADED', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-load-type/-t-r-a-c-k_-l-o-a-d-e-d/index.html', 'searchKey':'TRACK_LOADED'},
+{'name': 'data class NullablePlaylistInfo(name: String?, selectedTrack: Int?)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.NullablePlaylistInfo', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-nullable-playlist-info/index.html', 'searchKey':'NullablePlaylistInfo'},
+{'name': 'fun NullablePlaylistInfo(name: String?, selectedTrack: Int?)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.NullablePlaylistInfo.NullablePlaylistInfo', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-nullable-playlist-info/-nullable-playlist-info.html', 'searchKey':'NullablePlaylistInfo'},
+{'name': 'data class PlaylistInfo(name: String, selectedTrack: Int)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.PlaylistInfo', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-playlist-info/index.html', 'searchKey':'PlaylistInfo'},
+{'name': 'fun PlaylistInfo(name: String, selectedTrack: Int)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.PlaylistInfo.PlaylistInfo', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-playlist-info/-playlist-info.html', 'searchKey':'PlaylistInfo'},
+{'name': 'data class Track(track: String, info: TrackResponse.Track.Info)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/index.html', 'searchKey':'Track'},
+{'name': 'fun Track(track: String, info: TrackResponse.Track.Info)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Track', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-track.html', 'searchKey':'Track'},
+{'name': 'data class Info(identifier: String, isSeekable: Boolean, author: String, length: Long, isStream: Boolean, position: Int, title: String, uri: String)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/index.html', 'searchKey':'Info'},
+{'name': 'fun Info(identifier: String, isSeekable: Boolean, author: String, length: Long, isStream: Boolean, position: Int, title: String, uri: String)', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.Info', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/-info.html', 'searchKey':'Info'},
+{'name': 'operator fun component3(): String', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.component3', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/component3.html', 'searchKey':'component3'},
+{'name': 'operator fun component3(): List', 'description':'me.schlaubi.lavakord.rest.TrackResponse.component3', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/component3.html', 'searchKey':'component3'},
+{'name': 'operator fun component4(): Long', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.component4', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/component4.html', 'searchKey':'component4'},
+{'name': 'operator fun component4(): TrackResponse.Error?', 'description':'me.schlaubi.lavakord.rest.TrackResponse.component4', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/component4.html', 'searchKey':'component4'},
+{'name': 'operator fun component5(): Boolean', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.component5', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/component5.html', 'searchKey':'component5'},
+{'name': 'operator fun component6(): Int', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.component6', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/component6.html', 'searchKey':'component6'},
+{'name': 'operator fun component7(): String', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.component7', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/component7.html', 'searchKey':'component7'},
+{'name': 'operator fun component8(): String', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.Info.component8', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/-info/component8.html', 'searchKey':'component8'},
+{'name': 'fun toAudioTrack(): AudioTrack', 'description':'me.schlaubi.lavakord.rest.TrackResponse.Track.toAudioTrack', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/-track/to-audio-track.html', 'searchKey':'toAudioTrack'},
+{'name': 'fun getException(): TrackResponse.Error', 'description':'me.schlaubi.lavakord.rest.TrackResponse.getException', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/get-exception.html', 'searchKey':'getException'},
+{'name': 'fun getPlaylistInfo(): TrackResponse.PlaylistInfo', 'description':'me.schlaubi.lavakord.rest.TrackResponse.getPlaylistInfo', 'location':'lavakord/me.schlaubi.lavakord.rest/-track-response/get-playlist-info.html', 'searchKey':'getPlaylistInfo'},
+{'name': 'fun List.mapToAudioTrack(): List', 'description':'me.schlaubi.lavakord.rest.mapToAudioTrack', 'location':'lavakord/me.schlaubi.lavakord.rest/map-to-audio-track.html', 'searchKey':'mapToAudioTrack'}]
diff --git a/example/src/main/kotlin/me/schlaubi/lavakord/example/Lavakord.kt b/example/src/main/kotlin/me/schlaubi/lavakord/example/Lavakord.kt
index 443ccbaf..002d33e8 100644
--- a/example/src/main/kotlin/me/schlaubi/lavakord/example/Lavakord.kt
+++ b/example/src/main/kotlin/me/schlaubi/lavakord/example/Lavakord.kt
@@ -16,8 +16,6 @@ import com.gitlab.kordlib.kordx.commands.model.prefix.literal
import com.gitlab.kordlib.kordx.commands.model.prefix.or
import com.gitlab.kordlib.kordx.commands.model.prefix.prefix
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler
-import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager
-import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist
import com.sedmelluq.discord.lavaplayer.track.AudioTrack
@@ -76,8 +74,15 @@ fun testModule(): ModuleModifier = module("music-test") {
}
}
+ command("ban") {
+ invoke {
+ kord.rest.guild.addRoleToGuildMember(guild!!.id.value, "416902379598774273", "723204343930683423", "D.js is better than Kord")
+ }
+ }
+
command("play") {
invoke(StringArgument) { query ->
+
val search = if (query.startsWith("http")) {
query
} else {
diff --git a/src/main/kotlin/me/schlaubi/lavakord/rest/LinkExtensions.kt b/src/main/kotlin/me/schlaubi/lavakord/rest/LinkTrackExtensions.kt
similarity index 98%
rename from src/main/kotlin/me/schlaubi/lavakord/rest/LinkExtensions.kt
rename to src/main/kotlin/me/schlaubi/lavakord/rest/LinkTrackExtensions.kt
index d5f2239a..42502d5e 100644
--- a/src/main/kotlin/me/schlaubi/lavakord/rest/LinkExtensions.kt
+++ b/src/main/kotlin/me/schlaubi/lavakord/rest/LinkTrackExtensions.kt
@@ -14,8 +14,7 @@ import me.schlaubi.lavakord.asKordLink
import me.schlaubi.lavakord.audio.KordLink
private val client = HttpClient {
- install(JsonFeature) {
- }
+ install(JsonFeature)
}
/**
@@ -81,7 +80,6 @@ private suspend fun KordLink.loadItem(query: String): TrackResponse {
return client.get(url.build()) {
headers["Authorization"] = node.password
- println(headers)
}
}
diff --git a/src/main/kotlin/me/schlaubi/lavakord/rest/TrackResponse.kt b/src/main/kotlin/me/schlaubi/lavakord/rest/TrackResponse.kt
index 3dd7aa65..332e1cf3 100644
--- a/src/main/kotlin/me/schlaubi/lavakord/rest/TrackResponse.kt
+++ b/src/main/kotlin/me/schlaubi/lavakord/rest/TrackResponse.kt
@@ -4,7 +4,16 @@ import com.sedmelluq.discord.lavaplayer.tools.FriendlyException
import com.sedmelluq.discord.lavaplayer.track.AudioTrack
import kotlinx.serialization.Serializable
import lavalink.client.LavalinkUtil
+import me.schlaubi.lavakord.rest.TrackResponse.*
+/**
+ * A Response from the Lavalink [Track Loading API](https://github.com/Frederikam/Lavalink/blob/master/IMPLEMENTATION.md#track-loading-api)
+ *
+ * @property loadType the type of the response
+ * @property playlistInfo the [PlaylistInfo] if available otherwise an empty [NullablePlaylistInfo]
+ * @property tracks a list of [Tracks](Track) found
+ * @property exception the [Error] if present
+ */
@Serializable
data class TrackResponse(
val loadType: LoadType,
@@ -15,28 +24,85 @@ data class TrackResponse(
val exception: Error? = null
) {
+ /**
+ * Returns the [PlaylistInfo] if present.
+ *
+ * @see playlistInfo
+ * @throws IllegalStateException when the [loadType] is not [LoadType.PLAYLIST_LOADED]
+ */
fun getPlaylistInfo(): PlaylistInfo =
if (loadType == LoadType.PLAYLIST_LOADED) playlistInfo.notNull() else error("Playlist info is only available for LoadType.PLAYLIST_LOADED")
+ /**
+ * Returns the [Error] if present.
+ *
+ * @see exception
+ * @throws IllegalStateException when the [loadType] is not [LoadType.LOAD_FAILED]
+ */
fun getException(): Error =
if (loadType == LoadType.LOAD_FAILED) exception!! else error("Exception is only available for LoadType.LOAD_FAILED")
+ /**
+ * The type of the response.
+ */
enum class LoadType {
+ /**
+ * Returned when a single track is loaded.
+ */
TRACK_LOADED,
+
+ /**
+ * Returned when a playlist is loaded.
+ *
+ * @see PlaylistInfo
+ * @see TrackResponse.playlistInfo
+ */
PLAYLIST_LOADED,
+
+ /**
+ * Returned when a search result is made (i.e ytsearch: some song).
+ */
SEARCH_RESULT,
+
+ /**
+ * Returned if no matches/sources could be found for a given identifier.
+ */
NO_MATCHES,
+
+ /**
+ * Returned if Lavaplayer failed to load something for some reason.
+ *
+ * @see Error
+ * @see TrackResponse.exception
+ */
LOAD_FAILED
}
+ /**
+ * An Error reported from lavalink/lavaplayer.
+ *
+ * @property message the message of the error
+ * @property severity the [FriendlyException.Severity] of the error.
+ *
+ * @see LoadType.LOAD_FAILED
+ */
@Serializable
data class Error(
val message: String,
val severity: FriendlyException.Severity
) {
+ /**
+ * Converts the error into a [FriendlyException].
+ */
fun toFriendlyException(): FriendlyException = FriendlyException(message, severity, null)
}
+ /**
+ * A [PlaylistInfo] that can contain nothing.
+ *
+ * @property name the name of the playlist
+ * @property selectedTrack the index of the selected track
+ */
@Serializable
data class NullablePlaylistInfo(
val name: String? = null,
@@ -45,18 +111,46 @@ data class TrackResponse(
internal fun notNull() = PlaylistInfo(name!!, selectedTrack!!)
}
+ /**
+ * A [PlaylistInfo] that cannot contain nothing.
+ *
+ * @property name the name of the playlist
+ * @property selectedTrack the index of the selected track
+ */
data class PlaylistInfo(
val name: String,
val selectedTrack: Int
)
+ /**
+ * A Track.
+ *
+ * @property track the base64 encoded track
+ * @property info the parsed [Info]
+ */
@Serializable
data class Track(
val track: String,
val info: Info
) {
+
+ /**
+ * Converts this track to an [AudioTrack].
+ */
fun toAudioTrack(): AudioTrack = LavalinkUtil.toAudioTrack(track)
+ /**
+ * The track information.
+ *
+ * @property identifier the identifier created by the tracks source
+ * @property isSeekable whether you can use [AudioTrack.setPosition] I think lavadoc does not tell me
+ * @property author the author of the track
+ * @property length the length of the track in ms
+ * @property isStream whether the track is a stream or not
+ * @property position the current position of the track in milliseconds
+ * @property title the title of the track
+ * @property uri the uri to the track
+ */
@Serializable
data class Info(
val identifier: String,