Skip to content

Commit

Permalink
Add translations, commands, and messages necessary for party Marathon…
Browse files Browse the repository at this point in the history
… system
  • Loading branch information
FluxCapacitor2 committed Dec 23, 2024
1 parent b45e104 commit 2bd9be8
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 5 deletions.
2 changes: 1 addition & 1 deletion common/src/main/kotlin/com/bluedragonmc/server/Game.kt
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ abstract class Game(val name: String, val mapName: String, val mode: String? = n
protected val eventNode = EventNode.event("$name-$mapName-$mode", EventFilter.ALL) { event ->
try {
when (event) {
is InstanceEvent -> ownsInstance(event.instance)
is InstanceEvent -> ownsInstance(event.instance ?: return@event false)
is GameEvent -> event.game === this
is PlayerEvent -> event.player.isActive && ownsInstance(event.player.instance ?: return@event false)
is ServerTickMonitorEvent -> true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ interface OutgoingRPCHandler {
suspend fun transferParty(partyOwner: Player, newOwner: UUID)
suspend fun listPartyMembers(member: UUID): PartyListResponse

// Party Marathons
suspend fun startMarathon(player: UUID, durationMs: Int)
suspend fun endMarathon(player: UUID)
suspend fun getMarathonLeaderboard(players: Collection<UUID>, silent: Boolean)
suspend fun recordCoinAward(player: UUID, coins: Int, gameId: String)

// Jukebox controls
suspend fun getSongInfo(player: Player): PlayerSongQueue
suspend fun playSong(player: Player, songName: String, queuePosition: Int, startTimeInTicks: Int, tags: List<String>): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,22 @@ class OutgoingRPCHandlerStub : OutgoingRPCHandler {
return PartySvc.PartyListResponse.getDefaultInstance()
}

override suspend fun startMarathon(player: UUID, durationMs: Int) {

}

override suspend fun endMarathon(player: UUID) {

}

override suspend fun getMarathonLeaderboard(players: Collection<UUID>, silent: Boolean) {

}

override suspend fun recordCoinAward(player: UUID, coins: Int, gameId: String) {

}

override suspend fun getSongInfo(player: Player): JukeboxOuterClass.PlayerSongQueue {
return playerSongQueue {
isPlaying = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.bluedragonmc.server.*
import com.bluedragonmc.server.model.PlayerDocument
import com.bluedragonmc.server.service.Database
import com.bluedragonmc.server.module.GameModule
import com.bluedragonmc.server.service.Messaging
import com.bluedragonmc.server.utils.*
import kotlinx.coroutines.launch
import net.kyori.adventure.sound.Sound
Expand All @@ -19,7 +20,11 @@ import java.time.Duration

class AwardsModule : GameModule() {

override fun initialize(parent: Game, eventNode: EventNode<Event>) {}
private lateinit var parent: Game

override fun initialize(parent: Game, eventNode: EventNode<Event>) {
this.parent = parent
}

fun awardCoins(player: Player, amount: Int, reason: Component) {
player as CustomPlayer
Expand All @@ -28,6 +33,7 @@ class AwardsModule : GameModule() {
Database.IO.launch {
player.data.compute(PlayerDocument::coins) { it + amount }
player.data.compute(PlayerDocument::experience) { it + amount }
Messaging.outgoing.recordCoinAward(player.uuid, amount, parent.id)
val newLevel = CustomPlayer.getXpLevel(player.data.experience).toInt()
if (newLevel > oldLevel)
MinecraftServer.getSchedulerManager().buildTask { notifyLevelUp(player, oldLevel, newLevel) }
Expand Down
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ okhttp = "4.10.0"
serialization = "1.5.0-RC"
tinylog = "2.6.2"
# Auto-generated GRPC/Protobuf messaging code
rpc = "53da6cbfed"
rpc = "18b740c038"
# Agones SDK and its necessary runtime dependencies
agones-kt = "0.1.2"
grpc = "1.50.2"
Expand All @@ -32,6 +32,7 @@ serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serializ
caffeine = { group = "com.github.ben-manes.caffeine", name = "caffeine", version.ref = "caffeine" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
rpc = { group = "com.github.bluedragonmc", name = "rpc", version.ref = "rpc" }
#rpc = { group = "com.bluedragonmc", name = "rpc", version = "1.0" }
grpc-protobuf = { group = "io.grpc", name = "grpc-protobuf", version.ref = "grpc" }
grpc-netty = { group = "io.grpc", name = "grpc-netty", version.ref = "grpc" }
grpc-kotlin-stub = { group = "io.grpc", name = "grpc-kotlin-stub", version.ref = "grpc-kotlin-stub" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ object Commands : Bootstrap() {
MessageCommand("msg", "message", "w", "tell"),
MindecraftesCommand("mindecraftes", "/mindecraftes"),
PardonCommand("pardon", "/pardon <player|ban ID>", "unban", "unmute"),
PartyCommand("party", "/party <invite|kick|promote|warp|chat|list> ...", "p"),
PartyCommand("party", "/party <invite|kick|promote|warp|chat|list|marathon> ...", "p"),
PartyChatShorthandCommand("pchat", "/pc <message>", "pc", "partychat"),
PingCommand("ping", "/ping", "latency"),
PlaysoundCommand("playsound", "/playsound <sound> <source> <target> [position] [volume] [pitch]", "ps"),
Expand Down
32 changes: 32 additions & 0 deletions src/main/kotlin/com/bluedragonmc/server/command/PartyCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class PartyCommand(name: String, usageString: String, vararg aliases: String) :
warp
chat <message>
list
marathon start <minutes>
marathon end
marathon leaderboard
*/

subcommand("invite") {
Expand Down Expand Up @@ -93,6 +96,35 @@ class PartyCommand(name: String, usageString: String, vararg aliases: String) :
}
}

subcommand("marathon") {
usage("/party marathon <start|end|leaderboard> [...]")

subcommand("start") {
usage("/party marathon start [minutes]")
val minutesArgument by IntArgument
suspendSyntax(minutesArgument) {
val minutes = get(minutesArgument)
if (minutes in 5..300) {
Messaging.outgoing.startMarathon(player.uuid, get(minutesArgument) * 60 * 1_000)
} else {
sender.sendMessage(Component.translatable("puffin.party.marathon.invalid_time", NamedTextColor.RED))
}
}
}

subcommand("end") {
suspendSyntax {
Messaging.outgoing.endMarathon(player.uuid)
}
}

subcommand("leaderboard") {
suspendSyntax {
Messaging.outgoing.getMarathonLeaderboard(setOf(player.uuid), false)
}
}
}

// If the player adds a player as the first argument instead of typing `invite <player>`
val playerArgument by OfflinePlayerArgument
suspendSyntax(playerArgument) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.bluedragonmc.server.module.DependsOn
import com.bluedragonmc.server.module.GameModule
import com.bluedragonmc.server.module.instance.InstanceModule
import com.bluedragonmc.server.service.Messaging
import com.bluedragonmc.server.utils.GameState
import com.bluedragonmc.server.utils.listen
import com.bluedragonmc.server.utils.listenAsync
import com.bluedragonmc.server.utils.miniMessage
Expand All @@ -25,6 +26,7 @@ import net.minestom.server.event.instance.AddEntityToInstanceEvent
import net.minestom.server.event.player.PlayerDisconnectEvent
import net.minestom.server.event.player.PlayerSpawnEvent
import net.minestom.server.instance.Instance
import java.time.Duration
import java.util.*
import java.util.concurrent.TimeUnit

Expand Down Expand Up @@ -57,6 +59,14 @@ class OutgoingRPCHandlerImpl(serverAddress: String, serverPort: Int) : OutgoingR

eventNode.listenAsync<GameStateChangedEvent> { event ->
Messaging.outgoing.updateGameState(parent.id, event.game.rpcGameState)

if (event.newState == GameState.ENDING) {
MinecraftServer.getSchedulerManager().buildTask {
Messaging.IO.launch {
Messaging.outgoing.getMarathonLeaderboard(event.game.players.map { it.uuid }, true)
}
}.delay(Duration.ofSeconds(2)).schedule()
}
}

eventNode.listenAsync<AddEntityToInstanceEvent> { event ->
Expand Down Expand Up @@ -297,6 +307,42 @@ class OutgoingRPCHandlerImpl(serverAddress: String, serverPort: Int) : OutgoingR
)
}

override suspend fun startMarathon(player: UUID, durationMs: Int) {
partyStub.withDeadlineAfter(5, TimeUnit.SECONDS).startMarathon(
PartySvc.StartMarathonRequest.newBuilder()
.setPlayerUuid(player.toString())
.setDurationMs(durationMs)
.build()
)
}

override suspend fun endMarathon(player: UUID) {
partyStub.withDeadlineAfter(5, TimeUnit.SECONDS).stopMarathon(
PartySvc.StopMarathonRequest.newBuilder()
.setPlayerUuid(player.toString())
.build()
)
}

override suspend fun getMarathonLeaderboard(players: Collection<UUID>, silent: Boolean) {
partyStub.withDeadlineAfter(5, TimeUnit.SECONDS).getMarathonLeaderboard(
PartySvc.MarathonLeaderboardRequest.newBuilder()
.addAllPlayerUuids(players.map { it.toString() })
.setSilent(silent)
.build()
)
}

override suspend fun recordCoinAward(player: UUID, coins: Int, gameId: String) {
partyStub.withDeadlineAfter(5, TimeUnit.SECONDS).recordCoinAward(
PartySvc.RecordCoinAwardRequest.newBuilder()
.setPlayerUuid(player.toString())
.setCoins(coins)
.setGameId(gameId)
.build()
)
}

override suspend fun getSongInfo(player: Player): JukeboxOuterClass.PlayerSongQueue {
return jukeboxStub.withDeadlineAfter(5, TimeUnit.SECONDS).getSongInfo(songInfoRequest {
playerUuid = player.uuid.toString()
Expand Down
15 changes: 14 additions & 1 deletion src/main/resources/lang_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -485,4 +485,17 @@ puffin.party.list.members=Members ({0}): {1}
puffin.party.list.not_found=You are not in a party.

puffin.queue.not_enough_space=You couldn't be sent to {0}: Server is full
puffin.party.game_join_disallowed.not_leader=You must be the leader of a party to do this.
puffin.party.game_join_disallowed.not_leader=You must be the leader of a party to do this.

puffin.party.marathon_already_started=Your party already has a marathon in progress!
puffin.party.marathon.not_leader=You must be the party leader to do this.
puffin.party.marathon.started={0} has started a Marathon!\nCoins earned by party members will be tallied for the next {1}.\nThe player with the most coins gained wins!
puffin.party.marathon.started.time_period=\u23F0 {0} minutes
puffin.party.marathon.ended=Time's Up! The Marathon has ended!
puffin.party.marathon.ended_by_player={0} has ended the Marathon!
puffin.party.marathon.not_found=Your party does not have an active Marathon!
puffin.party.marathon.current_leaderboard=Current Marathon leaderboard:
puffin.party.marathon.current_leaderboard.no_points=No one has earned any coins yet! Earn coins to earn a place on your party's Marathon leaderboard.
puffin.party.marathon.invalid_time=The Marathon duration must be between 5 and 300 minutes.
puffin.party.marathon.time_remaining=Time remaining: {0} hours, {1} minutes, {2} seconds
puffin.party.marathon.outside_points=Note: Coins earned in games without the rest of your party don't count towards your party's Marathon.

0 comments on commit 2bd9be8

Please sign in to comment.