initial commit
All checks were successful
CI / deploy (push) Successful in 7m36s
CI / deploy (pull_request) Successful in 6m6s

This commit is contained in:
Arindy
2025-02-09 20:54:04 +01:00
parent 650f147700
commit ca538e7980
86 changed files with 55337 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
package de.arindy.dicetower
import io.quarkus.runtime.annotations.RegisterForReflection
import jakarta.enterprise.context.ApplicationScoped
import jakarta.ws.rs.Consumes
import jakarta.ws.rs.GET
import jakarta.ws.rs.POST
import jakarta.ws.rs.Path
import jakarta.ws.rs.PathParam
import jakarta.ws.rs.Produces
import jakarta.ws.rs.core.Context
import jakarta.ws.rs.core.MediaType
import jakarta.ws.rs.sse.OutboundSseEvent
import jakarta.ws.rs.sse.Sse
import jakarta.ws.rs.sse.SseBroadcaster
import jakarta.ws.rs.sse.SseEventSink
import java.util.UUID
@Path("/dice/{id}")
@ApplicationScoped
final class DiceResource(@Context val sse: Sse) {
private var eventBuilder: OutboundSseEvent.Builder = sse.newEventBuilder()
private var sseBroadcasters: MutableMap<String, SseBroadcaster> = HashMap()
@POST
@Consumes(MediaType.APPLICATION_JSON)
fun parseCommand(@PathParam("id") id: String, data: RollPayload) {
if (!sseBroadcasters.containsKey(id)) {
sseBroadcasters[id] = sse.newBroadcaster()
}
data.roll = data.command.split(" ").toTypedArray<String>()
data.room = id.split(":")[0]
data.user = id.split(":")[1]
sseBroadcasters[id]?.broadcast(
eventBuilder.id((UUID.randomUUID()).toString())
.mediaType(MediaType.APPLICATION_JSON_TYPE).data(data).build()
)
if (data.roll.all { it.trim().isNotEmpty() }) {
results(data.room!!, Result(data.name))
}
}
@POST
@Path("/results")
@Consumes(MediaType.APPLICATION_JSON)
fun results(@PathParam("id") id: String, data: Any) {
sseBroadcasters[id]?.broadcast(
eventBuilder.id((UUID.randomUUID()).toString())
.mediaType(MediaType.APPLICATION_JSON_TYPE).data(data).build()
)
}
@GET
@Path("/stream")
@Produces(MediaType.SERVER_SENT_EVENTS)
fun stream(@PathParam("id") id: String, @Context sseEventSink: SseEventSink) {
if (!sseBroadcasters.containsKey(id)) {
sseBroadcasters[id] = sse.newBroadcaster()
}
sseBroadcasters[id]?.register(sseEventSink)
}
@GET
@Path("/results")
@Produces(MediaType.SERVER_SENT_EVENTS)
fun results(@PathParam("id") id: String, @Context sseEventSink: SseEventSink) {
if (!sseBroadcasters.containsKey(id)) {
sseBroadcasters[id] = sse.newBroadcaster()
}
sseBroadcasters[id]?.register(sseEventSink)
}
@RegisterForReflection
data class Result(val name: String) {}
}

View File

@@ -0,0 +1,18 @@
package de.arindy.dicetower
import io.quarkus.qute.TemplateInstance
import jakarta.ws.rs.GET
import jakarta.ws.rs.Path
import jakarta.ws.rs.PathParam
import jakarta.ws.rs.Produces
import jakarta.ws.rs.core.MediaType
@Path("overlay/{diceid}")
class OverlayResource {
@GET
@Produces(MediaType.TEXT_HTML)
fun get(@PathParam("diceid") diceid: String): TemplateInstance {
return Templates.overlay(diceid)
}
}

View File

@@ -0,0 +1,12 @@
package de.arindy.dicetower
data class RollPayload(
val name: String,
var command: String,
val themeColor: String = "white",
val theme: String = "default",
var room: String?,
var user: String?,
) {
lateinit var roll: Array<String>
}

View File

@@ -0,0 +1,10 @@
package de.arindy.dicetower
import io.quarkus.qute.CheckedTemplate
import io.quarkus.qute.TemplateInstance
@CheckedTemplate
object Templates {
@JvmStatic
external fun overlay(diceid: String): TemplateInstance
}