Skip to content

Commit

Permalink
Show instance states as part of lobby signs by the door (available / …
Browse files Browse the repository at this point in the history
…in-use / rebuilding)

Resolves #43
  • Loading branch information
4Ply committed Feb 13, 2025
1 parent d562723 commit f7bcfd9
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 5 deletions.
107 changes: 102 additions & 5 deletions src/main/kotlin/org/trackedout/citadel/StatusTaskRunner.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package org.trackedout.citadel

import com.mongodb.client.model.Filters
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.TextComponent
import net.kyori.adventure.text.format.NamedTextColor
import net.kyori.adventure.text.minimessage.MiniMessage
import net.megavex.scoreboardlibrary.api.sidebar.Sidebar
import org.bukkit.Material
import org.bukkit.block.Block
import org.bukkit.block.sign.Side
import org.bukkit.scheduler.BukkitRunnable
import org.trackedout.citadel.mongo.DungeonState
import org.trackedout.citadel.mongo.MongoDBManager
import org.trackedout.citadel.mongo.MongoDungeon
import org.trackedout.client.apis.StatusApi
import org.trackedout.fs.logger

// WARNING: This task is processed *asynchronously*, and thus most interactions with the main Minecraft thread
// must go through a sync task scheduler. The Scoreboard lib is thread-safe, so it doesn't require a sync task.
Expand Down Expand Up @@ -34,11 +42,8 @@ class StatusTaskRunner(
statusSection.lines?.forEach {
val parsed = mm.deserialize(it.key!!)

val textComponent: TextComponent = Component.text()
.append(parsed)
.append(Component.text(": "))
.append(Component.text("${it.value!!}").colorIfAbsent(NamedTextColor.AQUA))
.build()
val textComponent: TextComponent =
Component.text().append(parsed).append(Component.text(": ")).append(Component.text("${it.value!!}").colorIfAbsent(NamedTextColor.AQUA)).build()
sidebar.line(lines++, textComponent)
}
}
Expand All @@ -50,5 +55,97 @@ class StatusTaskRunner(
sidebar.removePlayer(it)
}
}

updateDungeonStatusSigns()
}

private fun updateDungeonStatusSigns() {
logger.debug("Starting dungeon status sign updater")
val database = MongoDBManager.getDatabase("dunga-dunga");
val instanceCollection = database.getCollection("instances", MongoDungeon::class.java)
val instancesByState = instanceCollection.find(
Filters.and(
Filters.regex("name", "^d[0-9]{3}"),
)
).groupBy { it.state }

val signConfigs = mapOf(
listOf(DungeonState.AVAILABLE) to Sign(-537, 117, 1975) { instances ->
listOf(
"",
"${instances.size} Available",
"Inhaleable",
)
},

listOf(
DungeonState.RESERVED,
DungeonState.AWAITING_PLAYER,
) to Sign(-537, 116, 1975) { instances ->
listOf(
"",
"${instances.size} Pending",
"Player Sending",
)
},

listOf(DungeonState.IN_USE) to Sign(-537, 115, 1975) { instances ->
listOf(
"",
"${instances.size} In Use",
"Caboose",
)
},

listOf(
DungeonState.BUILDING,
DungeonState.UNREACHABLE
) to Sign(-537, 114, 1975) { instances ->
listOf(
"",
"${instances.size} Resetti",
"Spaghetti",
)
}
)

signConfigs.entries.forEach { (states, signConfig) ->
val instances = states.flatMap { state ->
val dbState = state.toString().lowercase().replace("_", "-")
instancesByState[dbState] ?: emptyList()
}

val lines = signConfig.text(instances)
plugin.runOnNextTick {
updateSign(signConfig.x, signConfig.y, signConfig.z, lines)
}
}
}

private fun updateSign(x: Int, y: Int, z: Int, lines: List<String>) {
logger.debug("Updating sign at $x, $y, $z with lines: $lines")

plugin.server.worlds.find { it.name == "world" }?.let { world ->
val signBlock: Block = world.getBlockAt(x, y, z)

if (signBlock.type == Material.WARPED_WALL_SIGN) {
val sign = signBlock.state as org.bukkit.block.Sign
val signSide = sign.getSide(Side.FRONT)

intArrayOf(0, 1, 2, 3).forEach { i ->
signSide.line(i, Component.text(lines.getOrNull(i) ?: "").color(NamedTextColor.WHITE))
}

sign.update()
}
}
}

data class Sign(
val x: Int,
val y: Int,
val z: Int,
// Takes in the list of instances, and returns a list of up to 4 strings to display on the sign
val text: (instances: List<MongoDungeon>) -> List<String>,
)
}
43 changes: 43 additions & 0 deletions src/main/kotlin/org/trackedout/citadel/mongo/MongoDungeon.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.trackedout.citadel.mongo

import org.bson.codecs.pojo.annotations.BsonId
import org.bson.types.ObjectId
import java.time.Instant

data class MongoDungeon(
@BsonId val id: ObjectId,

val name: String,
val ip: String,
val state: String,

val activePlayers: Long,
val requiresRebuild: Boolean,
val inUseDate: Instant? = null,

val healthySince: Instant? = null,
val unhealthySince: Instant? = null,

val createdAt: Instant,
val updatedAt: Instant,
)

/*
export enum InstanceStates {
AVAILABLE = 'available', // ready for use
RESERVED = 'reserved', // assigned to a player, waiting for the player to be notified
AWAITING_PLAYER = 'awaiting-player', // player notified + attempted teleport to the dungeon
IN_USE = 'in-use', // player has connected to the dungeon
BUILDING = 'building', // starting up / rebuilding
UNREACHABLE = 'unreachable', // health-checks failed
}
*/

enum class DungeonState {
AVAILABLE,
RESERVED,
AWAITING_PLAYER,
IN_USE,
BUILDING,
UNREACHABLE
}

0 comments on commit f7bcfd9

Please sign in to comment.