Skip to content

Commit

Permalink
feat: add simple frontend for in-game preview
Browse files Browse the repository at this point in the history
  • Loading branch information
MiniDigger committed Oct 3, 2024
1 parent cc3e70d commit ec82846
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 36 deletions.
6 changes: 2 additions & 4 deletions src/commonMain/kotlin/net/kyori/adventure/webui/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@ public const val PARAM_EDITOR_TOKEN: String = "token"
/** Path for getting a short link for a MiniMessage input. */
public const val URL_MINI_SHORTEN: String = "/mini-shorten"

/** Path for getting a hostname for an in-game MiniMessage motd preview. */
public const val URL_SETUP_MOTD_PREVIEW: String = "/setup-motd-preview"
/** Path for getting a hostname for an in-game MiniMessage kick preview. */
public const val URL_SETUP_KICK_PREVIEW: String = "/setup-kick-preview"
/** Path for getting a hostname for an in-game MiniMessage preview. */
public const val URL_IN_GAME_PREVIEW: String = "/in-game-preview"

/** Path for getting the configuration of this WebUI instance */
public const val URL_BUILD_INFO: String = "/build"
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ public data class Combined(
public val background: String? = null,
public val mode: String? = null
)

@Serializable
public data class InGamePreview(
public val miniMessage: String? = null,
public val key: String? = null
)
3 changes: 3 additions & 0 deletions src/commonMain/resources/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ <h1 class="title mc-font">MiniMessage Viewer</h1>
<button class="button" id="copy-button" aria-label="Copy input" title="Copy input">
<span class="icon is-small"><i class="fas fa-copy"></i></span>
</button>
<button class="button" id="in-game-preview-button" aria-label="Try in-game" title="Try in-game">
<span class="icon is-small"><i class="fas fa-gamepad"></i></span>
</button>
<div class="dropdown share-dropdown">
<div class="dropdown-trigger">
<button class="button" aria-haspopup="true" aria-controls="share-dropdown-menu">
Expand Down
16 changes: 16 additions & 0 deletions src/jsMain/kotlin/net/kyori/adventure/webui/js/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ import net.kyori.adventure.webui.URL_API
import net.kyori.adventure.webui.URL_EDITOR
import net.kyori.adventure.webui.URL_EDITOR_INPUT
import net.kyori.adventure.webui.URL_EDITOR_OUTPUT
import net.kyori.adventure.webui.URL_IN_GAME_PREVIEW
import net.kyori.adventure.webui.URL_MINI_TO_HTML
import net.kyori.adventure.webui.URL_MINI_TO_JSON
import net.kyori.adventure.webui.URL_MINI_TO_TREE
import net.kyori.adventure.webui.editor.EditorInput
import net.kyori.adventure.webui.tryDecodeFromString
import net.kyori.adventure.webui.websocket.Call
import net.kyori.adventure.webui.websocket.Combined
import net.kyori.adventure.webui.websocket.InGamePreview
import net.kyori.adventure.webui.websocket.Packet
import net.kyori.adventure.webui.websocket.Placeholders
import net.kyori.adventure.webui.websocket.Response
Expand Down Expand Up @@ -323,6 +325,20 @@ public fun mainLoaded() {
}
)

var inGamePreviewKey = (1..8).map { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".random() }.joinToString("")
document.getElementById("in-game-preview-button")!!.addEventListener(
"click",
{
window.postPacket(
"$URL_API$URL_IN_GAME_PREVIEW",
InGamePreview(miniMessage = input.value, key = inGamePreviewKey)
)
.then { response -> response.text() }
.then { text -> window.navigator.clipboard.writeText(text) }
.then { bulmaToast.toast("Minecraft Server Hostname copied to clipboard!") }
}
)

// EDITOR

// BURGER MENU
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ import net.kyori.adventure.webui.Serializers
import net.kyori.adventure.webui.URL_API
import net.kyori.adventure.webui.URL_BUILD_INFO
import net.kyori.adventure.webui.URL_EDITOR
import net.kyori.adventure.webui.URL_IN_GAME_PREVIEW
import net.kyori.adventure.webui.URL_MINI_SHORTEN
import net.kyori.adventure.webui.URL_MINI_TO_HTML
import net.kyori.adventure.webui.URL_MINI_TO_JSON
import net.kyori.adventure.webui.URL_MINI_TO_TREE
import net.kyori.adventure.webui.URL_SETUP_KICK_PREVIEW
import net.kyori.adventure.webui.URL_SETUP_MOTD_PREVIEW
import net.kyori.adventure.webui.jvm.appendComponent
import net.kyori.adventure.webui.jvm.getConfigString
import net.kyori.adventure.webui.jvm.minimessage.editor.installEditor
Expand All @@ -49,6 +48,7 @@ import net.kyori.adventure.webui.jvm.minimessage.storage.BytebinStorage
import net.kyori.adventure.webui.tryDecodeFromString
import net.kyori.adventure.webui.websocket.Call
import net.kyori.adventure.webui.websocket.Combined
import net.kyori.adventure.webui.websocket.InGamePreview
import net.kyori.adventure.webui.websocket.Packet
import net.kyori.adventure.webui.websocket.ParseResult
import net.kyori.adventure.webui.websocket.Placeholders
Expand Down Expand Up @@ -205,16 +205,14 @@ public fun Application.miniMessage() {
}
}

post(URL_SETUP_MOTD_PREVIEW) {
val input = call.receiveText()
val hostname = previewManager.initializeMotdPreview(input)
call.respondText(hostname)
}

post(URL_SETUP_KICK_PREVIEW) {
val input = call.receiveText()
val hostname = previewManager.initializeKickPreview(input)
call.respondText(hostname)
post(URL_IN_GAME_PREVIEW) {
val request = Serializers.json.tryDecodeFromString<InGamePreview>(call.receiveText())
if (request != null && request.miniMessage != null && request.key != null) {
val hostname = previewManager.initializePreview(request.miniMessage, request.key)
call.respondText(hostname)
} else {
call.response.status(HttpStatusCode.BadRequest)
}
}

get(URL_BUILD_INFO) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ public class ServerStatusPreviewManager(
private val managerJob = SupervisorJob(application.coroutineContext.job)
override val coroutineContext: CoroutineContext = application.coroutineContext + managerJob

private val motdPreviews = Cache.Builder<String, String>().expireAfterAccess(1.hours).build()
private val kickPreviews = Cache.Builder<String, String>().expireAfterAccess(1.hours).build()
private val previews = Cache.Builder<String, String>().expireAfterAccess(1.hours).build()

init {
launch {
Expand Down Expand Up @@ -110,32 +109,18 @@ public class ServerStatusPreviewManager(
}

private fun lookupKickMessage(serverAddress: String): String {
return kickPreviews.get(serverAddress.split(".")[0]) ?: "<red>You cant join here!"
return previews.get(serverAddress.split(".")[0]) ?: "<red>You cant join here!"
}

private fun lookupMotd(serverAddress: String): String {
return motdPreviews.get(serverAddress.split(".")[0]) ?: "<rainbow>MiniMessage is cool!"
return previews.get(serverAddress.split(".")[0]) ?: "<rainbow>MiniMessage is cool!"
}

public fun initializeKickPreview(input: String): String {
val key = generateRandomString()
kickPreviews.put(key, input)
public fun initializePreview(input: String, key: String): String {
previews.put(key, input)
return "$key.webui.advntr.dev"
}

public fun initializeMotdPreview(input: String): String {
val key = generateRandomString()
motdPreviews.put(key, input)
return "$key.webui.advntr.dev"
}

private fun generateRandomString(length: Int = 8): String {
val allowedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
return (1..length)
.map { allowedChars.random() }
.joinToString("")
}

private suspend fun ByteWriteChannel.writeMcPacket(packetId: Int, consumer: (packet: DataOutputStream) -> Unit) {
val stream = ByteArrayOutputStream()
val packet = DataOutputStream(stream)
Expand Down

0 comments on commit ec82846

Please sign in to comment.