From da525d517ab99a3623e77a6dbdf9df3b6ea4de1d Mon Sep 17 00:00:00 2001
From: viztea <hi@vzt.gay>
Date: Tue, 12 Dec 2023 03:58:06 -0800
Subject: [PATCH] feat: implement media sink wants

---
 voice/src/main/kotlin/gateway/Command.kt               | 10 ++++++++++
 voice/src/main/kotlin/gateway/DefaultVoiceGateway.kt   |  3 ++-
 .../main/kotlin/gateway/DefaultVoiceGatewayBuilder.kt  |  2 ++
 voice/src/main/kotlin/gateway/OpCode.kt                |  3 ++-
 .../main/kotlin/gateway/handler/HandshakeHandler.kt    |  1 +
 5 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/voice/src/main/kotlin/gateway/Command.kt b/voice/src/main/kotlin/gateway/Command.kt
index 163678a7c58f..4dffe4b2b400 100644
--- a/voice/src/main/kotlin/gateway/Command.kt
+++ b/voice/src/main/kotlin/gateway/Command.kt
@@ -31,6 +31,10 @@ public sealed class Command {
                     composite.encodeSerializableElement(descriptor, 0, OpCode.Serializer, OpCode.Heartbeat)
                     composite.encodeLongElement(descriptor, 1, value.nonce)
                 }
+                is MediaSinkWants -> {
+                    composite.encodeSerializableElement(descriptor, 0, OpCode.Serializer, OpCode.MediaSinkWants)
+                    composite.encodeSerializableElement(descriptor, 1, MediaSinkWants.serializer(), value)
+                }
                 is SendSpeaking -> {
                     composite.encodeSerializableElement(descriptor, 0, OpCode.Serializer, OpCode.Speaking)
                     composite.encodeSerializableElement(descriptor, 1, SendSpeaking.serializer(), value)
@@ -72,6 +76,12 @@ public data class SendSpeaking(
     val ssrc: UInt
 ) : Command()
 
+@KordVoice
+@Serializable
+public data class MediaSinkWants(
+    val any: Int
+) : Command()
+
 @KordVoice
 @Serializable
 public data class SelectProtocol(
diff --git a/voice/src/main/kotlin/gateway/DefaultVoiceGateway.kt b/voice/src/main/kotlin/gateway/DefaultVoiceGateway.kt
index 9469a04f78c7..1f1cd1a4ebd2 100644
--- a/voice/src/main/kotlin/gateway/DefaultVoiceGateway.kt
+++ b/voice/src/main/kotlin/gateway/DefaultVoiceGateway.kt
@@ -37,6 +37,7 @@ public data class DefaultVoiceGatewayData(
     val sessionId: String,
     val client: HttpClient,
     val reconnectRetry: Retry,
+    val isDeaf: Boolean,
     val eventFlow: MutableSharedFlow<VoiceEvent>
 )
 
@@ -196,7 +197,7 @@ public class DefaultVoiceGateway(
                     val copy = command.copy(data = command.data.copy(address = "ip"))
                     "Voice Gateway >>> ${Json.encodeToString(Command.SerializationStrategy, copy)}"
                 }
-                is Heartbeat, is Resume, is SendSpeaking -> "Voice Gateway >>> $json"
+                else -> "Voice Gateway >>> $json"
             }
         }
         socket.send(Frame.Text(json))
diff --git a/voice/src/main/kotlin/gateway/DefaultVoiceGatewayBuilder.kt b/voice/src/main/kotlin/gateway/DefaultVoiceGatewayBuilder.kt
index fa9426296d50..140ce46b8661 100644
--- a/voice/src/main/kotlin/gateway/DefaultVoiceGatewayBuilder.kt
+++ b/voice/src/main/kotlin/gateway/DefaultVoiceGatewayBuilder.kt
@@ -21,6 +21,7 @@ public class DefaultVoiceGatewayBuilder(
     public var client: HttpClient? = null
     public var reconnectRetry: Retry? = null
     public var eventFlow: MutableSharedFlow<VoiceEvent> = MutableSharedFlow(extraBufferCapacity = Int.MAX_VALUE)
+    public var isDeaf: Boolean = false
 
     public fun build(): DefaultVoiceGateway {
         val client = client ?: HttpClient(CIO) {
@@ -37,6 +38,7 @@ public class DefaultVoiceGatewayBuilder(
             sessionId,
             client,
             retry,
+            isDeaf,
             eventFlow
         )
 
diff --git a/voice/src/main/kotlin/gateway/OpCode.kt b/voice/src/main/kotlin/gateway/OpCode.kt
index 4a9f0bf7224f..ef2b668287c5 100644
--- a/voice/src/main/kotlin/gateway/OpCode.kt
+++ b/voice/src/main/kotlin/gateway/OpCode.kt
@@ -19,7 +19,8 @@ public enum class OpCode(public val code: Int) {
     Resume(7),
     Hello(8),
     Resumed(9),
-    ClientDisconnect(13);
+    ClientDisconnect(13),
+    MediaSinkWants(15);
 
     internal object Serializer : KSerializer<OpCode> {
         override val descriptor: SerialDescriptor
diff --git a/voice/src/main/kotlin/gateway/handler/HandshakeHandler.kt b/voice/src/main/kotlin/gateway/handler/HandshakeHandler.kt
index a9241fa77201..30838e39ceee 100644
--- a/voice/src/main/kotlin/gateway/handler/HandshakeHandler.kt
+++ b/voice/src/main/kotlin/gateway/handler/HandshakeHandler.kt
@@ -23,6 +23,7 @@ internal class HandshakeHandler(
         on<Hello> {
             data.reconnectRetry.reset()
             send(identify)
+            send(MediaSinkWants(if (data.isDeaf) 0 else 100))
         }
     }
 }