GithubHelp home page GithubHelp logo

kordlib / lavalink.kt Goto Github PK

View Code? Open in Web Editor NEW
35.0 2.0 10.0 9.55 MB

Coroutine based client for Lavalink (Kotlin and Java)

License: MIT License

Kotlin 97.84% Java 2.16%
kotlin kotlin-js kord ktor wrapper discord lavalink hacktoberfest

lavalink.kt's People

Contributors

bytealex avatar drschlaubi avatar emmaboecker avatar freyacodes avatar mooner1022 avatar nycodeghg avatar toxicmushroom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

lavalink.kt's Issues

Unsupported version

According to the documentation I wrote a bot using JDA and Java. After much effort, I got a message that the Lavalink 4.0.0-beta3 version was unsupported, and then the connection was no longer possible at all. "Handshake failed due to invalid Upgrade header: null"

What version of Lavalink Lavalink.kt 5.1.7 supports then?

java.lang.NumberFormatException: For input string: "Snowflake(value=***)"

Lavakord is sending guild id as guildId.toString() where guildId is Snowflake, which leads to error on the lavalink node org.json.JSONException: JSONObject["guildId"] is not a long. <- java.lang.NumberFormatException: For input string: "Snowflake(value=***)"
Having a brief look into the source code, I found at least here snowflake is being sent as just string representation: LavaKordImpl.kt/KordLavaKord.class/handleVoiceServerUpdate/80 line and 82 line

Initially, issue was found when I tried to play a track and no sound was coming from a bot

Missing access for reading filter values

There is currently no good way to read previously configured filter values from the player.

The current filters variable is only inside the WebsocketPlayer class and marked internal
This could be abstracted into Player and made public to allow for reading the filter values

Websocket connection errors are not being handled correctly on Kotlin/JS

Currently, whenever an error occurs in the WebSocket connection the following JS error is being printed and kills the nodejs process

      var exception = new WebSocketException(JSON.stringify(event));
                                                  ^
TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Socket'
    |     property 'parser' -> object with constructor 'HTTPParser'
    --- property 'socket' closes the circle
    at JSON.stringify (<anonymous>)
    at WebSocket.<anonymous> (D:\WORK\lavakord\build\js\node_modules\ktor-ktor-client-core-jsLegacy\ktor-ktor-client-core-jsLegacy.js:17440:51)
    at WebSocket.onError (D:\WORK\lavakord\build\js\node_modules\ws\lib\event-target.js:128:16)
    at WebSocket.emit (events.js:311:20)
    at abortHandshake (D:\WORK\lavakord\build\js\node_modules\ws\lib\websocket.js:718:15)
    at ClientRequest.<anonymous> (D:\WORK\lavakord\build\js\node_modules\ws\lib\websocket.js:595:7)
    at ClientRequest.emit (events.js:311:20)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:603:27)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17)
    at Socket.socketOnData (_http_client.js:476:22)```

As this error gets thrown whilst Ktor is trying to turn the JS Error into a Ktor exception Lavakord cannot catch it. This also prevents Lavakord from reconnecting and resuming the connection

I created a Ktor issue here: https://youtrack.jetbrains.com/issue/KTOR-1726

Edit 1: Reconnecting works when the client is able to reconnect on the 1st try, but as soon as an exception has to be handled KTOR throws a javascript error which kills the whole process

Error when loading track

2024-01-19 18:47:33.142 [DefaultDispatcher-worker-15] TRACE i.k.client.plugins.HttpCallValidator - Processing exception io.ktor.serialization.JsonConvertException: Illegal input: Fields [pluginInfo, userData] are required for type with serial name 'dev.arbjerg.lavalink.protocol.v4.Track', but they were missing at path: $ for request http://82.67.2.160:2333/v4/loadtracks?identifier=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQloMdg2bapw
2024-01-19 18:47:33.143 [DefaultDispatcher-worker-15] ERROR dev.kord.core.Kord - catching
io.ktor.serialization.JsonConvertException: Illegal input: Fields [pluginInfo, userData] are required for type with serial name 'dev.arbjerg.lavalink.protocol.v4.Track', but they were missing at path: $
	at io.ktor.serialization.kotlinx.KotlinxSerializationConverter.deserialize(KotlinxSerializationConverter.kt:90)
	at io.ktor.serialization.ContentConverterKt$deserialize$$inlined$map$1$2.emit(Emitters.kt:224)
	at kotlinx.coroutines.flow.FlowKt__BuildersKt$asFlow$$inlined$unsafeFlow$3.collect(SafeCollector.common.kt:118)
	at io.ktor.serialization.ContentConverterKt$deserialize$$inlined$map$1.collect(SafeCollector.common.kt:113)
	at kotlinx.coroutines.flow.FlowKt__ReduceKt.firstOrNull(Reduce.kt:243)
	at kotlinx.coroutines.flow.FlowKt.firstOrNull(Unknown Source)
	at io.ktor.serialization.ContentConverterKt.deserialize(ContentConverter.kt:123)
	at io.ktor.client.plugins.contentnegotiation.ContentNegotiation.convertResponse$ktor_client_content_negotiation(ContentNegotiation.kt:230)
	at io.ktor.client.plugins.contentnegotiation.ContentNegotiation$Plugin$install$2.invokeSuspend(ContentNegotiation.kt:262)
	at io.ktor.client.plugins.contentnegotiation.ContentNegotiation$Plugin$install$2.invoke(ContentNegotiation.kt)
	at io.ktor.client.plugins.contentnegotiation.ContentNegotiation$Plugin$install$2.invoke(ContentNegotiation.kt)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:120)
	at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:78)
	at io.ktor.client.HttpClient$4.invokeSuspend(HttpClient.kt:177)
	at io.ktor.client.HttpClient$4.invoke(HttpClient.kt)
	at io.ktor.client.HttpClient$4.invoke(HttpClient.kt)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:120)
	at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:78)
	at io.ktor.client.plugins.logging.Logging$setupResponseLogging$2.invokeSuspend(Logging.kt:201)
	at io.ktor.client.plugins.logging.Logging$setupResponseLogging$2.invoke(Logging.kt)
	at io.ktor.client.plugins.logging.Logging$setupResponseLogging$2.invoke(Logging.kt)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:120)
	at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:78)
	at io.ktor.util.pipeline.SuspendFunctionGun.proceedWith(SuspendFunctionGun.kt:88)
	at io.ktor.client.plugins.HttpCallValidator$Companion$install$2.invokeSuspend(HttpCallValidator.kt:142)
	at io.ktor.client.plugins.HttpCallValidator$Companion$install$2.invoke(HttpCallValidator.kt)
	at io.ktor.client.plugins.HttpCallValidator$Companion$install$2.invoke(HttpCallValidator.kt)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:120)
	at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:78)
	at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:98)
	at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77)
	at io.ktor.client.call.HttpClientCall.bodyNullable(HttpClientCall.kt:89)
	at dev.schlaubi.lavakord.rest.LinkTrackExtensionsKt.loadItem(LinkTrackExtensions.kt:80)
	at dev.schlaubi.lavakord.rest.LinkTrackExtensionsKt$loadItem$2.invokeSuspend(LinkTrackExtensions.kt)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:589)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:806)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:710)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:697)
Caused by: kotlinx.serialization.MissingFieldException: Fields [pluginInfo, userData] are required for type with serial name 'dev.arbjerg.lavalink.protocol.v4.Track', but they were missing at path: $
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:95)
	at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
	at io.ktor.serialization.kotlinx.KotlinxSerializationConverter.deserialize(KotlinxSerializationConverter.kt:82)
	... 39 common frames omitted
Caused by: kotlinx.serialization.MissingFieldException: Fields [pluginInfo, userData] are required for type with serial name 'dev.arbjerg.lavalink.protocol.v4.Track', but they were missing
	at kotlinx.serialization.internal.PluginExceptionsKt.throwMissingFieldException(PluginExceptions.kt:20)
	at dev.arbjerg.lavalink.protocol.v4.Track.<init>(player.kt:30)
	at dev.arbjerg.lavalink.protocol.v4.Track$$serializer.deserialize(player.kt:30)
	at dev.arbjerg.lavalink.protocol.v4.Track$$serializer.deserialize(player.kt:30)
	at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:61)
	at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
	at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
	at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:279)
	at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:294)
	at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:279)
	at dev.arbjerg.lavalink.protocol.v4.LoadResult$TrackLoaded$$serializer.deserialize(loadResult.kt:29)
	at dev.arbjerg.lavalink.protocol.v4.LoadResult$TrackLoaded$$serializer.deserialize(loadResult.kt:29)
	at dev.arbjerg.lavalink.protocol.v4.LoadResult$Serializer$selectDeserializer$$inlined$asPolymorphicDeserializer$1.deserialize(PolymorphicSerializer.kt:26)
	at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:61)
	at kotlinx.serialization.json.internal.AbstractJsonTreeDecoder.decodeSerializableValue(TreeJsonDecoder.kt:52)
	at kotlinx.serialization.json.internal.TreeJsonDecoderKt.readJson(TreeJsonDecoder.kt:25)
	at kotlinx.serialization.json.Json.decodeFromJsonElement(Json.kt:127)
	at kotlinx.serialization.json.JsonContentPolymorphicSerializer.deserialize(JsonContentPolymorphicSerializer.kt:94)
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
	... 41 common frames omitted
2024-01-19 18:47:33.166 [DefaultDispatcher-worker-5] DEBUG d.s.lavakord.audio.internal.NodeImpl - RESPONSE: 200 OK

Cannot use polymorphic serializers on JS (Required by Gateway and RoutePlanner API)

On Kotlin/JS explicitly declared serializer should be used for interfaces and enums without @Serializable annotation
SerializationException: Serializer for class 'GatewayPayload' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
On Kotlin/JS explicitly declared serializer should be used for interfaces and enums without @Serializable annotation
	at <global>.platformSpecificSerializerNotRegistered(kotlin\lavakord-jsIr-test.js:81560)
	at <global>.serializer(kotlin\lavakord-jsIr-test.js:76486)
	at json.CommandsTest.testPlayCommand(kotlin\lavakord-jsIr-test.js:104119)
	at _no_name_provided__471.invoke(kotlin\lavakord-jsIr-test.js:106732)
	at Context.<anonymous>(kotlin\lavakord-jsIr-test.js:106513)
	at <global>.processImmediate(internal/timers.js:456)

See: Kotlin/kotlinx.serialization#1078

Nodes do not attempt reconnecting after initial connection refused

After calling Lavakord.addNode() and encountering a refused connection, this exception is raised:

Exception in thread "DefaultDispatcher-worker-9" java.net.ConnectException: Connection refused
	at java.base/sun.nio.ch.Net.pollConnect(Native Method)
	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:673)
	at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:973)
	at io.ktor.network.sockets.SocketImpl.connect$ktor_network(SocketImpl.kt:50)
	at io.ktor.network.sockets.SocketImpl$connect$1.invokeSuspend(SocketImpl.kt)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)

The coroutine then ends without retrying, as retries are only done when ReconnectException is caught.

java.net.ConnectException is JVM specific, so I am unsure how to catch it in multiplatform code

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.