Skip to content

Commit 41ff0d5

Browse files
Implement outgoing Jukebox messaging
1 parent 7280322 commit 41ff0d5

File tree

4 files changed

+104
-5
lines changed

4 files changed

+104
-5
lines changed

common/src/main/kotlin/com/bluedragonmc/server/api/OutgoingRPCHandler.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.bluedragonmc.server.api
22

33
import com.bluedragonmc.api.grpc.CommonTypes.GameState
44
import com.bluedragonmc.api.grpc.CommonTypes.GameType
5+
import com.bluedragonmc.api.grpc.JukeboxOuterClass.PlayerSongQueue
56
import com.bluedragonmc.api.grpc.PartySvc.PartyListResponse
67
import com.bluedragonmc.api.grpc.PlayerTrackerOuterClass.QueryPlayerResponse
78
import com.bluedragonmc.server.Game
@@ -50,4 +51,11 @@ interface OutgoingRPCHandler {
5051
suspend fun transferParty(partyOwner: Player, newOwner: UUID)
5152
suspend fun listPartyMembers(member: UUID): PartyListResponse
5253

54+
// Jukebox controls
55+
suspend fun getSongInfo(player: Player): PlayerSongQueue
56+
suspend fun playSong(player: Player, songName: String, queuePosition: Int, startTimeInTicks: Int, tags: List<String>): Boolean
57+
suspend fun removeSongByName(player: Player, songName: String)
58+
suspend fun removeSongByTag(player: Player, matchTags: List<String>)
59+
suspend fun stopSongAndClearQueue(player: Player)
60+
5361
}

common/src/main/kotlin/com/bluedragonmc/server/api/OutgoingRPCHandlerStub.kt

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package com.bluedragonmc.server.api
22

3-
import com.bluedragonmc.api.grpc.CommonTypes
4-
import com.bluedragonmc.api.grpc.PartySvc
5-
import com.bluedragonmc.api.grpc.PlayerTrackerOuterClass
3+
import com.bluedragonmc.api.grpc.*
64
import com.bluedragonmc.server.Game
75
import net.kyori.adventure.text.Component
86
import net.minestom.server.command.CommandSender
@@ -100,4 +98,31 @@ class OutgoingRPCHandlerStub : OutgoingRPCHandler {
10098
return PartySvc.PartyListResponse.getDefaultInstance()
10199
}
102100

101+
override suspend fun getSongInfo(player: Player): JukeboxOuterClass.PlayerSongQueue {
102+
return playerSongQueue {
103+
isPlaying = false
104+
}
105+
}
106+
107+
override suspend fun playSong(
108+
player: Player,
109+
songName: String,
110+
queuePosition: Int,
111+
startTimeInTicks: Int,
112+
tags: List<String>,
113+
): Boolean {
114+
return false
115+
}
116+
117+
override suspend fun removeSongByName(player: Player, songName: String) {
118+
119+
}
120+
121+
override suspend fun removeSongByTag(player: Player, matchTags: List<String>) {
122+
123+
}
124+
125+
override suspend fun stopSongAndClearQueue(player: Player) {
126+
127+
}
103128
}

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ okhttp = "4.10.0"
1111
serialization = "1.5.0-RC"
1212
tinylog = "2.6.2"
1313
# Auto-generated GRPC/Protobuf messaging code
14-
rpc = "0953adbab3"
14+
rpc = "b7071251fb"
1515
# Agones SDK and its necessary runtime dependencies
1616
agones-kt = "0.1.2"
1717
grpc = "1.50.2"

src/main/kotlin/com/bluedragonmc/server/impl/OutgoingRPCHandlerImpl.kt

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import com.bluedragonmc.server.service.Messaging
1515
import com.bluedragonmc.server.utils.listen
1616
import com.bluedragonmc.server.utils.listenSuspend
1717
import com.bluedragonmc.server.utils.miniMessage
18+
import com.github.benmanes.caffeine.cache.Caffeine
19+
import io.grpc.ManagedChannel
1820
import io.grpc.ManagedChannelBuilder
1921
import kotlinx.coroutines.launch
2022
import kotlinx.coroutines.runBlocking
@@ -28,6 +30,7 @@ import net.minestom.server.event.instance.AddEntityToInstanceEvent
2830
import net.minestom.server.event.player.PlayerDisconnectEvent
2931
import net.minestom.server.event.player.PlayerSpawnEvent
3032
import net.minestom.server.instance.Instance
33+
import java.time.Duration
3134
import java.util.*
3235
import java.util.concurrent.TimeUnit
3336

@@ -111,6 +114,27 @@ class OutgoingRPCHandlerImpl(serverAddress: String) : OutgoingRPCHandler {
111114
private val queueStub = QueueServiceGrpcKt.QueueServiceCoroutineStub(channel)
112115
private val partyStub = PartyServiceGrpcKt.PartyServiceCoroutineStub(channel)
113116

117+
private val proxyChannelCache = Caffeine
118+
.newBuilder()
119+
.expireAfterAccess(Duration.ofMinutes(10))
120+
.evictionListener<String, ManagedChannel> { _, value, _ ->
121+
value?.shutdown()?.awaitTermination(10, TimeUnit.SECONDS)
122+
}
123+
.build<String, ManagedChannel>()
124+
125+
private fun getChannelToProxyOf(player: Player): ManagedChannel {
126+
val address = player.playerConnection.remoteAddress.toString()
127+
return proxyChannelCache.get(address) { _ ->
128+
ManagedChannelBuilder.forAddress(address, 50051)
129+
.defaultLoadBalancingPolicy("round_robin")
130+
.usePlaintext()
131+
.enableRetry()
132+
.build()
133+
}
134+
}
135+
136+
private fun getJukeboxStubOf(player: Player) = JukeboxGrpcKt.JukeboxCoroutineStub(getChannelToProxyOf(player))
137+
114138
override fun isConnected(): Boolean {
115139
return !channel.isShutdown && !channel.isTerminated && ::serverName.isInitialized
116140
}
@@ -299,4 +323,46 @@ class OutgoingRPCHandlerImpl(serverAddress: String) : OutgoingRPCHandler {
299323
.build()
300324
)
301325
}
302-
}
326+
327+
override suspend fun getSongInfo(player: Player): JukeboxOuterClass.PlayerSongQueue {
328+
return getJukeboxStubOf(player).getSongInfo(songInfoRequest {
329+
playerUuid = player.uuid.toString()
330+
})
331+
}
332+
333+
override suspend fun playSong(
334+
player: Player,
335+
songName: String,
336+
queuePosition: Int,
337+
startTimeInTicks: Int,
338+
tags: List<String>,
339+
): Boolean {
340+
return getJukeboxStubOf(player).playSong(playSongRequest {
341+
this.playerUuid = player.uuid.toString()
342+
this.songName = songName
343+
this.queuePosition = queuePosition
344+
this.startTimeTicks = startTimeInTicks
345+
tags.forEach { this.tags.add(it) }
346+
}).startedPlaying
347+
}
348+
349+
override suspend fun removeSongByName(player: Player, songName: String) {
350+
getJukeboxStubOf(player).removeSong(songRemoveRequest {
351+
this.playerUuid = player.uuid.toString()
352+
this.songName = songName
353+
})
354+
}
355+
356+
override suspend fun removeSongByTag(player: Player, matchTags: List<String>) {
357+
getJukeboxStubOf(player).removeSongs(batchSongRemoveRequest {
358+
this.playerUuid = player.uuid.toString()
359+
matchTags.forEach { this.matchTags.add(it) }
360+
})
361+
}
362+
363+
override suspend fun stopSongAndClearQueue(player: Player) {
364+
getJukeboxStubOf(player).stopSong(stopSongRequest {
365+
this.playerUuid = player.uuid.toString()
366+
})
367+
}
368+
}

0 commit comments

Comments
 (0)